Michael Emerson
Michael Emerson

Reputation: 1813

Twig escaping HTML and rendering as raw

I hope someone can assist me on this issue.

I am pulling details from a database to display on a twig template (using Symfony2) but the way in which it is saved in the db makes it difficult to interpret the HTML.

Basically, the HTML tags are already translated as entities in the table, e.g.:

<p>Bach Flower Crab Apple Remedy: the "cleansing" Remedy can be used both internally and externally </p><p><strong>

And so on. I have researched the rendering options in twig and tried the following (based on me rendering a loop of product descriptions):

{% set strategy = 'html' %}
{% autoescape 'html' %}
{{ product.description|escape('html')|raw }}
{% endautoescape %}

and also just:

{{ product.description|raw }}

The first method just echoes the existing content (as entities) and the second method just renders the HTML tags to the page as follows:

<p>Bach Flower Crab Apple Remedy: the "cleansing" Remedy can be used both internally and externally.</p><p><strong>...

So, as you can see, I cannot find a way to actually interpret the HTML tags in order to display the description as it should be.

Is there a way to do this? I can't do it in the PHP as all it's doing is sending an object to the template which is looped through:

public function showAction(Request $request, $store_id=0)
{
    $max = 1000;
    $repository = $this->getDoctrine()->getRepository('AppBundle:Product');
    $products = $repository->getProductsByStoreId($store_id,$max);
    $paginator  = $this->get('knp_paginator');
    $pagination = $paginator->paginate(
        $products,
        $request->query->get('page', 1),
        20
    );

    $return['products'] = $pagination;
    $return['categories'] = $this->getCategories();

    return $this->render('AppBundle:tables:productstable.html.twig', $return);
}

Upvotes: 3

Views: 14234

Answers (2)

deceze
deceze

Reputation: 522625

Your core issue is that you do not have HTML in your database to begin with. At best Twig could be outputting some HTML entities, which will render visibly as "<p>...", and at "worst" Twig will escape the text to render it accurately as it actually is, which is "&lt;p&gt;...". Expecting Twig to output actual HTML which will render a paragraph is unrealistic, since that's not what your original data contains at all.

You'll have to HTML-decode that text in PHP first, and then output it in Twig with ..|raw. raw means that Twig will output it as is without further escaping it. Since it's nonsense to get the data from the database to then html_entity_decode it, you need to fix your data input here! Don't HTML encode data which is going into the database, it serves no purpose.

Upvotes: 2

Eugene Bianov
Eugene Bianov

Reputation: 11

I think you have to write custom escaper plugin to decode html entities and use it like this:

{{ product.description|myawesomehtmlentitiesdecoder|raw }}

http://twig.sensiolabs.org/doc/filters/escape.html#custom-escapers for reference.

But generally, it's better to store HTML in database and then apply needed security filters on output.

Upvotes: 1

Related Questions