Comment traduire des fichiers .po Drupal avec l'IA

La plupart des gens associent les fichiers .po à WordPress, mais le format gettext est antérieur à WordPress de plusieurs décennies et alimente la traduction d'interface dans tout le monde open source. Drupal est l'un de ses plus grands utilisateurs. Si vous gérez un site Drupal multilingue, chaque libellé de menu, description de champ, message d'erreur et chaîne de module passe par des fichiers .po exactement comme dans WordPress, simplement avec un dialecte de marqueur de position et un flux de travail d'importation différents. Et tout comme WordPress, dès que votre site dépasse une poignée de chaînes, la traduction manuelle de ces fichiers devient un goulot d'étranglement.
Ce guide explique comment traduire des fichiers .po Drupal avec l'IA sans casser ce qui fait de Drupal... Drupal. Nous examinerons le système de traduction de Drupal, d'où proviennent réellement les chaînes, la syntaxe des marqueurs de position qui diffère de WordPress et qui doit absolument être préservée, ainsi que la boucle complète d'exportation, de traduction et de réimportation, y compris les commandes drush qui la rendent répétable.
Fonctionnement du système de traduction de Drupal
Drupal gère la traduction d'interface via le module central locale (parfois appelé "Interface Translation" dans les versions modernes de Drupal). Une fois activé, il gère une table de base de données des chaînes source et de leurs traductions par langue, et il peut importer et exporter ces traductions sous forme de fichiers .po gettext standard.
L'interface d'administration se trouve à l'adresse /admin/config/regional/translate. De là, vous pouvez rechercher les chaînes non traduites, les modifier en ligne et, surtout, importer un fichier .po pour charger des traductions en masse ou exporter l'état actuel vers un fichier .po pour une édition hors ligne. Ce cycle d'exportation/édition/importation est le flux de travail que nous optimisons.
Contrairement à WordPress, où chaque plugin et thème livre ses propres fichiers .po et .mo dans un répertoire languages/, Drupal centralise les chaînes d'interface dans sa base de données et considère le .po comme le format d'échange. Vous exportez, travaillez sur le fichier, puis le réimportez. L'étape de compilation .mo requise par WordPress est gérée en interne.
D'où proviennent les chaînes
Les chaînes Drupal proviennent de trois endroits, et une traduction complète doit les couvrir toutes :
- Le Core contient des milliers de chaînes traduisibles pour l'interface utilisateur d'administration, les formulaires et les messages système.
- Les modules Contrib (Views, Webform, Commerce, et les autres) enregistrent chacun leurs propres chaînes via la fonction
t(). - Les Thèmes contribuent aux chaînes de modèles, aux étiquettes de région et aux descriptions des paramètres de thème.
Lorsque vous exportez depuis /admin/config/regional/translate, vous pouvez limiter l'exportation aux chaînes traduites, non traduites ou à toutes les chaînes. Pour un nouveau cycle de traduction, l'exportation des seules chaînes non traduites vous donne un fichier .po ciblé avec exactement le travail qui reste à faire.
Une conséquence pratique de cette structure à trois sources : votre travail de traduction n'est jamais vraiment "terminé". Chaque fois que vous ajoutez un module contrib, activez une nouvelle fonctionnalité ou mettez à jour le cœur de Drupal, un nouveau lot d'entrées msgid non traduites apparaît dans les tables de localisation. C'est pourquoi les équipes Drupal considèrent la traduction comme un processus récurrent plutôt qu'une tâche de lancement unique. La même boucle d'exportation, de traduction et de réimportation s'exécute à chaque déploiement qui touche les modules, et plus cette boucle est rapide, moins la dette de traduction s'accumule entre les versions.
Il est également à noter que Drupal peut extraire automatiquement des traductions contribuées par la communauté depuis localize.drupal.org pour le cœur et les modules contrib populaires. Celles-ci couvrent les chaînes courantes, mais elles couvrent rarement vos modules personnalisés, votre thème ou la phraséologie spécifique au projet que votre site utilise réellement. L'écart entre la traduction communautaire et un site entièrement localisé est précisément le travail qu'un passage par l'IA comble rapidement.
Les marqueurs de position Drupal ne sont pas des marqueurs de position WordPress
Voici la chose la plus importante à comprendre avant d'envoyer un fichier .po Drupal à un traducteur IA : Drupal n'utilise pas les marqueurs de position de style printf %s et %1$s qui dominent WordPress. La fonction t() de Drupal utilise trois préfixes de marqueur de position distincts, chacun avec un comportement d'échappement différent :
@variable— la valeur est échappée HTML, la valeur par défaut sûre pour le texte fourni par l'utilisateur.%variable— la valeur est échappée et enveloppée dans le balisage d'emphase<em>.:placeholder— utilisé pour les attributs d'URL, passe par la désinfection d'URL.
Une chaîne source Drupal typique ressemble à ceci dans le fichier .po exporté :
#: core/modules/node/node.module
msgid "@count comments"
msgid_plural "@count comments"
msgstr[0] ""
msgstr[1] ""
#: core/modules/user/user.module
msgid "Welcome @name, you last logged in on %date."
msgstr ""
Si un traducteur change @count en @cuenta, remplace @name par le mot traduit pour "nom", ou insère un espace transformant @count en @ count, le marqueur de position ne correspond plus à ce que l'appel t() transmet. Drupal affiche alors le jeton littéral @count sur la page au lieu du nombre réel. La traduction semble terminée mais le site est visiblement cassé.
C'est le même type de bug qui affecte les chaînes %s de WordPress, et nous couvrons le principe général en profondeur dans comment traduire des fichiers PO sans casser les variables de code. La particularité de Drupal est simplement qu'il existe trois styles de marqueurs de position au lieu d'un seul, et un outil de traduction doit les reconnaître tous.
Pourquoi les traducteurs génériques échouent ici
Collez cette chaîne node.module dans une boîte de traduction automatique grand public et vous obtiendrez fréquemment @count déformé, le %date lié par <em> localisé en un jeton différent, ou les formes plurielles fusionnées en une seule. Aucun de ces outils n'a été conçu en tenant compte de la sémantique gettext. Ils traduisent du texte ; ils ne comprennent pas que @count est un contrat avec le code de l'application.
Un pipeline de traduction compatible gettext avec Verrouillage de syntaxe traite @variable, %variable et :placeholder comme des jetons immuables. Ils sont verrouillés avant la traduction et restaurés après, de sorte que la phrase environnante est traduite tandis que les marqueurs de position passent intacts. Le même verrou couvre %s et %1$s de WordPress, {{name}} de i18next et le HTML en ligne, c'est pourquoi un seul outil peut servir un projet Drupal, Symfony ou Laravel aussi facilement qu'un projet WordPress. Les formes plurielles de Drupal via msgid_plural sont préservées en tant que formes plurielles plutôt que d'être aplaties, ce qui est important car les langues Drupal peuvent avoir d'une à six variantes plurielles.
Il existe également un mode d'échec plus subtil qui mérite d'être souligné. Les chaînes Drupal intègrent fréquemment des balises et des liens en ligne dans le texte traduisible, comme Read the <a href=":url">documentation</a> où :url est un marqueur de position et où les balises <a> doivent survivre. Un traducteur qui ne comprend pas la structure peut traduire l'attribut href, supprimer la balise de fermeture ou localiser le nom du marqueur de position. Une IA consciente du contexte qui lit la chaîne entière comme une unité, combinée au verrouillage des jetons, maintient à la fois le balisage et le contrat :url intacts tout en ne traduisant que le texte "documentation" lisible par l'homme entre les deux.
La boucle d'exportation, de traduction et de réimportation
Le flux de travail reproductible comporte trois étapes, et drush rend l'exportation et l'importation scriptables afin que vous n'ayez pas à cliquer à travers l'interface utilisateur d'administration à chaque fois.
Étape 1 : Exporter le fichier PO
Vous pouvez exporter depuis l'interface utilisateur à l'adresse /admin/config/regional/translate en choisissant une langue et une portée d'exportation, ou le faire depuis la ligne de commande. Le module de localisation expose l'exportation via les services de traduction de Drupal, et la plupart des équipes le scriptent. Une invocation drush typique pour déclencher une importation de traduction (l'inverse, que nous utilisons à l'étape trois) ressemble à ceci :
# Re-import a translated PO file for Spanish, overwriting customized strings
drush locale:import es /var/www/translations/es-untranslated.po \
--type=customized --override=all
# Rebuild caches so the new strings render immediately
drush cache:rebuild
Pour l'exportation, le formulaire d'exportation d'administration produit le fichier .po ; de nombreuses équipes encapsulent le service d'exportation de localisation dans une petite commande Drush personnalisée pour une automatisation complète. Dans tous les cas, vous obtenez un fichier .po gettext standard contenant vos entrées msgid non traduites.
Étape 2 : Traduire le fichier
C'est l'étape où l'IA remplace des heures d'édition manuelle. Téléchargez le fichier .po exporté vers un traducteur cloud, choisissez votre langue cible et laissez-le traiter. Parce que les fichiers .po Drupal pour un grand site dépassent régulièrement les 10 Mo une fois le cœur, les modules contrib et les thèmes combinés, le Traitement par lots intelligent est important ici : le fichier est découpé, traduit et réassemblé sans que vous ayez à le diviser manuellement ou à atteindre des limites de taille. Le résultat est un fichier .po complet avec chaque msgstr rempli et chaque marqueur de position @count, %date et :url exactement là où il a commencé.
Étape 3 : Réimporter dans Drupal
Importez le fichier traduit via /admin/config/regional/translate ou via la commande drush locale:import présentée ci-dessus, puis reconstruisez le cache. Drupal fusionne les traductions dans ses tables de localisation, et les chaînes apparaissent immédiatement sur le site. Exécutez à nouveau la boucle chaque fois que vous ajoutez un module ou mettez à jour le cœur, car chacun apporte de nouvelles chaînes non traduites.
Un détail d'importation à bien gérer : l'option --override contrôle si les traductions entrantes remplacent les traductions existantes. Utilisez --override=all lorsque vous voulez que le fichier traduit par l'IA fasse autorité, ou un paramètre plus conservateur si vous avez ajusté manuellement certaines chaînes dans l'interface utilisateur de Drupal et que vous ne voulez pas qu'elles soient écrasées. Pour la plupart des pipelines automatisés, traiter le fichier .po comme la source de vérité et tout écraser rend le système prévisible : le fichier sous contrôle de version est ce que le site affiche, point final.
Pour les sites multilingues avec plusieurs langues cibles, la boucle s'exécute une fois par langue. Exportez l'ensemble non traduit, traduisez-le en allemand, importez-le ; exportez à nouveau, traduisez en espagnol, importez-le ; et ainsi de suite. Comme chaque langue est un fichier .po indépendant, vous pouvez les exécuter en parallèle, et un traducteur cloud les traitant simultanément transforme ce qui était auparavant une semaine de travail pour un contractuel en un après-midi.
Le format PO de Drupal n'est qu'un parmi plusieurs
Il convient de noter que le format gettext .po n'est pas la seule façon dont Drupal gère la traduction. Les entités de configuration et de contenu peuvent également être échangées en XLIFF, qui est la norme sur laquelle le module Translation Management Tool (TMGMT) s'appuie pour les flux de travail des fournisseurs de traduction professionnels. Si votre localisation Drupal passe par XLIFF plutôt que par des fichiers d'interface .po, les principes de préservation des marqueurs de position sont identiques mais la structure des fichiers diffère, et nous couvrons cette voie dans traduire des fichiers XLIFF pour Drupal, Symfony et Angular.
Pour la couche de traduction d'interface, cependant, le .po reste le cheval de bataille. La boucle d'exportation, de traduction par l'IA et de réimportation transforme une tâche manuelle de plusieurs jours en quelques minutes de traitement, et tant que l'outil que vous utilisez comprend réellement les marqueurs de position gettext, vos contrats @variable restent intacts et votre site Drupal reste fonctionnel dans toutes les langues que vous proposez.
Prêt à traduire vos fichiers
.poDrupal sans casser une seule@variable? Essayez SimplePoTranslate gratuitement — aucune carte de crédit requise. Le niveau gratuit gère les fichiers.poet.potgettext standard avec un Verrouillage de syntaxe complet, de sorte que vos marqueurs de position Drupal passent exactement comme le code s'y attend.