Accueil » Tous les articles » Magento 2 » Comment gérer la traduction dans AlpineJS ?

Comment gérer la traduction dans AlpineJS ?

Je me suis cassé la tête ces dernières semaines en essayant de gérer proprement les traductions côté JS sur Hyvä (poke EasierLabs). Knockout, dans l’écosystème Magento classique, supporte facilement des traductions côté client. Hyvä vend la performance et la simplicité, mais laisse ce genre de petites choses derrière. J’ai cherché des recettes, fouillé les forums, tenté des bricolages : la solution la plus fréquente que je trouvais revenait toujours au même pattern un peu moche — coller des x-show/x-text avec la traduction déjà résolue dans le .phtml sinon, passer par une constante window. Ça marche, mais ça force tout le rendu côté serveur et sabote un peu la propreté de l’interface JS quand on veut rester « minimal Alpine ».

<script>
    window.WORDING = "<?= $escaper->escapeJs($wording) ?>";
</script>
HTML

Puis

  const prefix = (window.WORDING && window.WORDING !== '') ? window.WORDING : '';
  const value = saving > 0 ? fmtPrice(saving) : fmtPrice(price);
  savingEl.textContent = `${prefix}${value}`;
JavaScript

C’est long et fastidieux.

Je refais mon plus vieux site, creationdeperso.com en ligne depuis le 12/02/2004 et encore en PHP5 sur un serveur en php7 (si, si). Je me suis dit que j’allais demander à mes stagiaires (Mistral, ChatGPT et Copilot) de le mettre au propre. C’était un moyen de voir comment chacun gère la migration de l’existant. J’ai voulu rester raisonnable : PHP pour le back, Twig pour le HTML parce que je ne suis pas totalement taré, et Alpine.js pour les interactions parce que je veux quelque chose de léger, sans bundler, sans pipeline compliqué. Bref : zero drama, max velocity (et pas totalement inconnu).

Le site est multilingue et c’est en essayant de gérer les traductions dans alpinejs avec twig que la lumière m’est apparue. Il existe un petit pattern simple, robuste et réutilisable : produire le JSON de traductions côté Twig (avec json_encode(JSON_UNESCAPED_UNICODE)), l’échapper pour un attribut HTML, puis le parser côté Alpine (x-init="translations = JSON.parse($el.dataset.translations)"). Résultat : pas de requêtes supplémentaires, pas de innerHTML dangereux, et la liberté d’écrire des helpers JS comme translateStat(key) côté Alpine.
Dans la suite, je te montre exactement comment faire — le code, les pièges à éviter (guillemets, retours à la ligne, double-encodage) et la version Magento/Hyvä adaptée.

Traduction dans Twig

Il faut génèrer ton tableau de traductions côté serveur, transformer en JSON sans échapper les caractères unicode, puis échapper pour un attribut HTML.

{# templates/_translations.twig #}
{% set translations = {
  "users": "Utilisateurs",
  "welcome": "Bienvenue \"ami\"",
  "multiline": "Ligne 1\nLigne 2"
} %}

<div
  x-data="translationsComponent()"
  x-init="translations = JSON.parse($el.dataset.translations)"
  data-translations="{{ translations|json_encode(constant('JSON_UNESCAPED_UNICODE'))|e('html_attr') }}"
>
  <p x-text="translateStat('welcome')"></p>
</div>

<script>
  function translationsComponent() {
    return {
      translations: {},
      translateStat(key){ return this.translations[key] ?? key; }
    }
  }
</script>
Twig

Points clés :

  • json_encode(JSON_UNESCAPED_UNICODE) → garde les accents lisibles.
  • |e('html_attr') → protège l’attribut data-… contre les guillemets et XSS.
  • Côté JS : JSON.parse($el.dataset.translations) est simple et sûr.

Traduction dans Hyvä

Il faut préparer les traductions dans un ViewModel.

public function getTranslationsJson(): string
{
    $translations = [
        'users' => __('Users')->render(),
        'welcome' => __('Welcome "%1"', 'ami')->render()
    ];
    return json_encode($translations, JSON_UNESCAPED_UNICODE);
}
PHP

Puis dans le phtml, on peut échapper le json

<?php $json = $vm->getTranslationsJson(); ?>
<div
  x-data="translationsComponent()"
  x-init="translations = JSON.parse($el.dataset.translations)"
  data-translations="<?= $block->escapeHtmlAttr($json); ?>"
>
  <p x-text="translateStat('welcome')"></p>
</div>
PHP

Conclusion

C’était pour la logique globale. J’ai conçu un petit module qui permet d’automatiser la récupération des traductions et de permettre l’utilisation de $t(‘chaîne à traduire’) dans le js comme dans x-text.

https://packagist.org/packages/crealoz/hyva-translations

Besoin d’aide pour mettre cela en place ?


Publié

dans

, ,

par

Commentaires

Laisser un commentaire