6

I would like to use variables containing HTML inside a trans tag in my Twig template. (The variables contain the start and the end of a link which appears at different positions in the sentence for different languages.)

There is some documentation about "Drupal 8 Twig Templates and Translations" which explains that for variables inside the trans tag there is a |placeholder-filter and a |raw-filter (for older versions: |passthrough).

I see no difference in the output using these filters.
Here is my template:

{% set string = '<strong>&amp;</strong>' %}
<div>
  {% trans %}
    Escaped: {{ string }}
  {% endtrans %}
</div>
<div>
  {% trans %}
    Pass-through: {{ string|raw }}
  {% endtrans %}
</div>
<div>
  {% trans %}
    Placeholder: {{ string|placeholder }}
  {% endtrans %}
</div>

And here ist the output:

Escaped: <strong>&amp;</strong>
Pass-through: <strong>&amp;</strong>
Placeholder: <strong>&amp;</strong>

Is there any filter that will switch off escaping?

1 Answer 1

10

AFAIK the Twig trans tag in Drupal 8 was implemented to ease translations to themers that were already familiar with Twig.

Under the hood, it's working with the same kind of translation strings as the regular Drupal translation function t() or the Drupal Twig filter |t, whereas all variables you are using within the trans block are handled as @variable or %variable placeholder within the translation strings.

These placeholders within the translation function always escape HTML before being inserted to the translation. No matter how you try to not escape the values you pass in, except you pass in a FormattableMarkup object.

Unsanitized variables ({{ variable|raw }} in Twig templates or !variable in translation strings) are deprecated for Drupal 8 translations and won't work in latest 8.x Drupal versions. The translation API description is a little outdated.

For your use case, you may just add the HTML link tag to your translation string and make the link URL itself the variable. Unfortunately, the Twig trans tag doesn't support that kind of variable yet. (Compare this core issue.) So you should use the t filter instead:

{{ 'A <a href=":url">link</a> example in a translation.'|t({ ':url': url }) }}

The above example matches the translation strings:

en: A <a href=":url">link</a> example in a translation.

de: Ein Beispiel-<a href=":url">Link</a> in einer Übersetzung.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.