Unescape or HTML Decode in Twig (PHP Templating)

Unescape or html decode in Twig (PHP Templating)

You can use the raw filter to make twig render raw html

http://twig.sensiolabs.org/doc/filters/raw.html

{% autoescape %}
{{ var|raw }} {# var won't be escaped #}
{% endautoescape %}

Decode HTML entities stored in MySQL with Twig (in Symfony)

Carefully control encodings.

The problem you are encountering is the simplest form of the nightmare that is character encoding. Rule one in handling encoding issues is to always control the encoding. In your case, this HTML should really be stored un-encoded in the DB, allowing for a single use of the twig raw output filter.

Consider the implications if you don't know whether the HTML needs to be decoded. For instance, if someone intended to show a < (<) in the text, and the html wasn't encoded, then applying html_entity_decode will turn that encoded < into a real one, and break the HTML. (Browsers will think you're starting a new TAG).

Forms submitting html

I'm going to guess that elsewhere in your app, there are forms which allow people to submit HTML. HTML forms encode data before posting, PHP $_POST handling usually auto applies htmlentities onto posted fields.

Whatever methods of your application are handling the storing of such Posted HTML, or add/changes these entities, should use html_entity_decode to ensure it is stored as raw html.

This way, you always know that HTML is stored in you database in exactly the state it needs to be rendered on the page. If it needs to be encoded and decoded again somewhere for some reason, you're not left hoping that some of the content won't be double-decoded. (Or as in your case, missing a decode step and spitting out raw HTML).

Rendering HTML in twig

One way or another, you need to get that content to your twig, passed through the raw filter, in the exact state it needs to be put on the page. While this can be done in twig, or with twig functions, this really should be done in the Controller.

Consider that path this data is traveling:

  1. Form (raw HTML)
  2. PHP POST (encoded HTML)
  3. DB (encoded HTML)
  4. SELECT Query
  5. PHP Controller (encoded HTML)
  6. Twig
  7. Rendered HTML

The earlier you can get the data in the correct state, the better. Doing so makes the data easier to work with, reduces the performance impact, and prevents code-duplication later in those steps. (What happens if you want to use this html in other Controllers or Twig templates? Code duplication.) Hense, my first suggestion to get it in the database cleanly.

If clean data is not an option...

Clean the data in your controller, maybe even with a static function in the entity.

The only other clean-ish way to handle this, is to loop through and decode the html before passing it to Twig. Doing it this way however, or later in the Tiwg template as you're currently doing, you run the risk of double-decoding that I mentioned earlier.

Veille

Class Veille
{

. . .

public static function decodeArray(?array $vielleList): ?array
{
foreach ($vielleList as $vielle) {
if (!$vielle instanceof self) {
continue;
}

$vielle->setVText(html_entity_decode($vielle->getVText()));
}

return $vielleList;
}

public function getVText(): ?string
{
return htmlentities("<h3>Encoded HTML Test</h3>Good data > parsing bad data.");
}

public function setVText(?string $text): void
{

}
}

Controller

$listactufree = $repository->findBy(
array('vStatus' => '4'), // Critere
array('vDatePublished' => 'desc'), // Tri
5, // Limite
0 // Offset
);

$listactufree = Veille::decodeArray($listactufree);

Twig

{% for veille in listactufree %}

{{ veille.vTexte|raw }}

{% endfor %}

Note, this same code could clean your data.

Plugging the contents of the decodeArray method into a command, and running that command, along with persist/flush, would store decoded HTML for all of your entities. Just make sure you only decode ONCE, and any methods which can add or edit these entities store the HTML unencoded. That's the key. Unencoded data.

How to escape entire block with html-entities via twig?

Twig does not by default escape template markup. If you wish to escape your HTML in this way, then set it to a variable first and then either autoescape it, or use a regular escape:

<rawXml>
<message>
{% set myHtml %}
<ThisShouldBeEscaped>
<ButItIsnt>Dang</ButItIsnt>
</ThisShouldBeEscaped>
{% endset %}
{% autoescape 'html' %}
{{ myHtml }}
{% endautoescape %}
<!-- or -->
{{ myHtml|escape }}
</message>
</rawXml>

Twig doesn't render html tags, |raw doesn't work

I don't know why you have <p>Lorem ipsum</p> as HTML content in your database, since it is NOT HTML, it is escaped HTML. Using raw unescapes the content, so your escaped HTML becomes... wait for it... HTML. And since twig escapes automatically HTML, that's why tags are displayed on your page.

What you could try as a quick fix is {{post.text|raw|raw}} to unescape the unescaped HTML. But honestly, what I would recommend for the sanity of your application is to unescape the HTML directly in your database. You SHOULD have <p>Lorem ipsum</p> in your database, then using {{post.text|raw}} should work perfectly.

html_entity_decode for twig (opencart)

Just register the html_entity_decode function in twig.
The most simple way is to look where twig is loaded and add the following code,

$twig->addFilter(new \Twig_Simple_Filter, 'html_entity_decode', 'html_entity_decode');

After that you can just do the following in your twig templates

{{ attribute.text|html_entity_decode }}

UPDATE: For Opencart 3.0.3.7 version filter should be like this:

$twig->addFilter(new \Twig\TwigFilter('html_entity_decode','html_entity_decode'));


Related Topics



Leave a reply



Submit