Ce qui se passe
Un message traduit a parfois besoin de HTML en son milieu, typiquement un lien dans
une phrase. La solution habituelle consiste à mettre ce HTML dans la traduction et à
l'afficher avec le filtre raw de Twig. Le billet de Symfony en liste les défauts :
les URL se retrouvent écrites en dur dans les fichiers de traduction, le HTML qu'un
traducteur ajoute s'affiche tel quel, et les paramètres du message ne sont plus
échappés. Si l'un d'eux contient une saisie utilisateur, on obtient une faille XSS.
Le filtre trans_html
Symfony 8.2 ajoute le filtre Twig trans_html, contribué par Hugo Alliaume
(pull request #66690). Les traductions ne contiennent plus de vrai HTML, seulement
des pseudo-balises sans attributs, du genre <name>…</name>. Dans le template,
chaque pseudo-balise est associée à l'élément à produire. Ces éléments se déclarent
comme des données (nom de balise et attributs), et on peut en passer une liste pour
les imbriquer, de l'extérieur vers l'intérieur.
Symfony rend les balises déclarées et échappe tout le reste : le texte du
message, les paramètres, les valeurs d'attributs, et toute balise que vous n'avez pas
déclarée. Si les balises de la traduction sont déséquilibrées, il échappe le message
entier. script et style sont interdits. La sortie du filtre est déjà sûre, donc
raw devient inutile, et le filtre fonctionne aussi avec les messages créés par la
fonction t().
Côté PHP, la nouvelle classe HtmlTranslator du composant Translation traduit
ces mêmes messages, par exemple pour construire des e-mails HTML.
Ce que ça change, et ce qui manque
- Les URL quittent les fichiers de traduction : le template les décide, pas le traducteur.
- Le billet est court et ses exemples de code ne figurent pas dans la matière que cette fiche a pu lire : la syntaxe exacte du template n'est pas reproduite ici, à prendre dans la documentation de Symfony 8.2.
- La 8.2 est en préparation : à essayer sur une traduction de test, pas à déployer.
Source : New in Symfony 8.2: Safer HTML in Translations, blog Symfony, 19 octobre 2026. Source en anglais.