Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a link inside translated content in Twig template

Tags:

twig

symfony

Inside a Twig template I would need to have a translated text that contains a link (the path should be generated by the Router, not statically embedded). Twig does not allow to render a variable inside a trans block - I'm also aware of the following:

{% trans with {'%name%': 'Fabien'} from "app" %}
Hello %name%
{% endtrans %}

but I can't see how to use that to inject inside the translation a piece like this

<a href="{{ path('privacy') }}">privacy policy</a>

(of course, the anchor text should be translated as well)

like image 423
Roberto Avatar asked Jul 18 '12 15:07

Roberto


3 Answers

The approach I've taken is this:

In the translation file:

page.privacy.policy: Please read our %link_start%privacy policy%link_end%

In the twig file:

<p>{{ 'page.privacy.policy' | trans({'%link_start%' : '<a href="'~path('privacy-policy')~'">', '%link_end%' : '</a>'}, 'account') | raw }}</p>

I'm not sure if this can be done using the block syntax you mentioned above as I found it didn't work unless I piped the result of the translation through the 'raw' filter. Also I use message domains to split the translations, hence the 'account' parameter.

I think the closest to your example would be:

<p>{{ 'Please read our %link_start%privacy policy%link_end%' | trans({'%link_start%' : '<a href="'~path('privacy-policy')~'">', '%link_end%' : '</a>'}) | raw }}</p>

EDIT:

The only issue with this approach I've come across is where I need to programmatically follow a translated link in a unit test as there isn't a single translation representing the link text. Although messy I think it would be possible to get round this by providing a separate translation for the link text and substituting it's translated value into the full text as an additional variable.

like image 126
redbirdo Avatar answered Nov 09 '22 06:11

redbirdo


rebdirdo's solution is not really safe as it's not escaping whole message. It is not working correctly for messages like "don't use <b> tag, use <strong> tag instead. %link_start%Here%link_end% you can find why.", because the tags will be not escaped and will be not visible.

working approach:

translation file:

advises.strong: don't use <b> tag, use <strong> tag instead. %link_start%Here%link_end% you can find why.

twig file:

{{ 'advises.strong'|trans|nl2br|replace({'%link_start%': '<a href="'~path('privacy-policy')~'">', '%link_end%': '</a>'})|raw }}

Note the nl2br filter. It is necessary to put some filter there to make the raw filter working only for the link tags.

like image 8
J4rmu1 Avatar answered Nov 09 '22 07:11

J4rmu1


This is a better way:

{{ 'Please read our %privacy_policy%'|trans({
    '%privacy_policy%': '<a href="' ~ path('privacypolicy') ~ '"> ' ~ 'Privacy Policy'|trans ~ '</a>'
})|raw }}
like image 3
the_nuts Avatar answered Nov 09 '22 05:11

the_nuts