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
This is a better way:
{{ 'Please read our %privacy_policy%'|trans({
'%privacy_policy%': '<a href="' ~ path('privacypolicy') ~ '"> ' ~ 'Privacy Policy'|trans ~ '</a>'
})|raw }}
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.
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.
Twig:
{{'body.term'|trans('%link_terms%' :app.request.getSchemeAndHttpHost()~path('terms')},'AcmeTerm')|raw }}
AcmeTerm.yml
body
term: >
<ul>
<li>Read<a href="%link_terms%">Terms</a>.</li>
</ul>
where path('terms') is the route like:
it__RG__terms ANY ANY ANY /it/termini-e-condizioni
en__RG__terms ANY ANY ANY /en/terms-and-conditions