Une agence partenaire, spécialisée dans les sites institutionnels multilingues, nous a sollicités pour un problème récurrent : à chaque mise en production, un chargé de projet devait se connecter en back-office, exporter manuellement les traductions modifiées depuis WPML, puis les réimporter sur l’environnement de production après le déploiement du code. Cette étape, purement manuelle, prenait en moyenne 25 minutes et générait régulièrement des oublis de traductions récentes.
Le problème n’était pas la qualité des traductions elles-mêmes, ni l’outil de traduction en tant que tel, mais bien l’absence d’automatisation de cette étape dans le pipeline de déploiement existant. Le pipeline gérait déjà correctement le code (thème, plugins, migrations de base via WP-CLI), mais traitait les traductions comme un angle mort.
Le problème posé
Le site utilise WPML avec une bonne partie du contenu géré en Translation Editor avancé, ce qui signifie que les traductions vivent en base de données, pas dans des fichiers de langue statiques. Sur un environnement de staging où les rédacteurs travaillent, ces traductions évoluent en continu. Lors d’un déploiement vers la production, il faut donc s’assurer que les traductions validées sur staging arrivent bien en production, sans écraser le contenu de production plus récent créé entre-temps par un autre canal (formulaires, commandes WooCommerce, etc.).
Le snippet retenu

La solution s’appuie sur la commande wp wpml disponible via l’extension officielle de commandes WP-CLI pour WPML, combinée à une étape dédiée dans le pipeline (GitLab CI dans ce cas précis, mais transposable à GitHub Actions). Le principe : exporter uniquement les traductions modifiées depuis le dernier déploiement, en filtrant par table et par date, plutôt que de dupliquer l’intégralité de la base.
# Étape "traductions" du pipeline .gitlab-ci.yml
deploy_translations:
stage: deploy
script:
- ssh $DEPLOY_USER@$DEPLOY_HOST "wp --path=$REMOTE_PATH wpml export
--post_type=page,post,formation
--since='24 hours ago'
--format=xliff
--output=/tmp/export-traductions.zip"
- scp $DEPLOY_USER@$DEPLOY_HOST:/tmp/export-traductions.zip ./exports/
- ssh $DEPLOY_USER@$PROD_HOST "wp --path=$PROD_PATH wpml import
--file=/tmp/export-traductions.zip
--duplicate-strategy=skip-if-modified"
only:
- main
Le paramètre --duplicate-strategy=skip-if-modified est le point le plus sensible du script : il évite d’écraser une traduction modifiée directement en production (rare, mais possible pour des corrections urgentes) par une version plus ancienne venue du staging. Cette option n’existe pas nativement dans toutes les versions du connecteur WP-CLI de WPML : nous avons dû l’implémenter via un filtre wpml_tm_import_strategy exposé par le plugin, faute d’option native équivalente à cette date.
Gérer le cas des nouvelles chaînes de thème
Un second problème, plus subtil, concerne les chaînes ajoutées par une mise à jour de thème ou de plugin déployée en même temps que le contenu. Ces chaînes n’existent pas encore dans la String Translation Table au moment de l’export. Nous avons ajouté une étape préalable qui force leur enregistrement avant l’export :
wp --path=$REMOTE_PATH eval '
do_action( "wpml_st_scan_theme_strings" );
do_action( "wpml_st_scan_plugin_strings" );
'
Sans cette étape, les nouvelles chaînes n’apparaissaient dans l’interface de traduction qu’après une visite manuelle de la page concernée par un administrateur — ce qui, en pratique, retardait leur traduction de plusieurs jours.
Variantes selon le contexte
- Petit site, faible fréquence de publication : un export/import quotidien planifié via une tâche cron suffit, pas besoin de le coupler à chaque déploiement de code.
- Site à forte volumétrie de contenu : filtrer l’export par type de contenu et par date évite des fichiers XLIFF de plusieurs dizaines de mégaoctets qui ralentissent le pipeline.
- Multi-environnements (staging, recette, prod) : chaîner les exports d’un environnement à l’autre plutôt que de tous les faire partir du même staging, pour éviter les conflits de versions de traduction.
Limites de cette approche
Cette automatisation ne remplace pas une politique claire de « source de vérité » : si des rédacteurs peuvent modifier le contenu traduit à la fois en staging et en production, des conflits resteront possibles quel que soit le niveau d’automatisation du pipeline. Nous avons donc imposé, en parallèle du script, une règle organisationnelle simple : toute modification de traduction passe désormais exclusivement par le staging, la production n’étant plus jamais éditée directement pour ce type de contenu.
Un script d’automatisation ne corrige jamais un problème de process ; il ne fait que le rendre plus visible, plus vite, et avec moins d’erreurs de copier-coller.
Pour aller plus loin
Sur ce projet, le temps de déploiement lié aux traductions est passé de 25 minutes à moins de deux minutes, et surtout, le risque d’oubli humain a disparu puisque l’étape est désormais systématique et journalisée dans les logs du pipeline. La prochaine amélioration envisagée est l’ajout d’une notification Slack listant les chaînes nouvellement détectées et non encore traduites, pour que l’équipe éditoriale les traite avant qu’elles n’atteignent la production en langue source par défaut.