# Des chaînes non traduites sur un site WordPress multilingue

> Un site WordPress multilingue affiche encore du texte dans la langue source par endroits : selon qu’il tourne sous WPML ou Polylang, la cause n’est jamais tout à fait la même, et une chaîne non traduite peut soit manquer d’être enregistrée quelque part, soit être structurellement impossible à traduire tant que le code n’a pas été corrigé.

- Source canonique : [https://allaux.fr/wordpress-woocommerce/problemes/traduction-incomplete](https://allaux.fr/wordpress-woocommerce/problemes/traduction-incomplete)
- Langue : FR
- Dernière mise à jour : 2026-08-03

## Réponse directe

> Cherchez d’abord la chaîne dans les fichiers du thème ou de l’extension et regardez si elle passe par __(), _e() ou esc_html__(). Écrite en dur dans un template, aucun outil ne la traduira : la correction se fait dans le code, de préférence depuis le functions.php d’un thème enfant. Si elle passe bien par gettext, c’est le text domain déclaré ou le fichier .mo chargé qui ne correspond pas.

## Comment je procède

1. **Localisation de la chaîne** — Je repère si la chaîne vient du thème, d’une extension WooCommerce, ou d’un texte injecté en JavaScript, parce que chacun de ces cas se traite d’une façon différente.
2. **Vérification du text domain** — Je vérifie que load_plugin_textdomain() ou load_theme_textdomain() charge bien le dossier /languages attendu et pointe vers le text domain déclaré dans l’en-tête du plugin ou du thème.
3. **Recherche dans le code** — Je cherche si la chaîne passe par __(), _e() ou esc_html__(). Si elle est écrite en dur dans un template ou un fichier PHP, elle n’a jamais été enregistrée comme traduisible, quel que soit l’outil utilisé.
4. **Traduction ou correction du code** — Pour une chaîne déjà enregistrée mais non traduite, je l’ajoute dans WPML String Translation ou l’éditeur de traductions Polylang. Pour une chaîne codée en dur, je corrige la source pour qu’elle passe par une fonction gettext.
5. **Vérification après mise à jour** — Je vérifie qu’une mise à jour récente du thème ou de l’extension n’a pas réinitialisé des traductions personnalisées stockées d’une façon qui se fait écraser au prochain déploiement.

## Ce que je traite régulièrement

- Un bouton, un message d’erreur ou un texte de panier reste dans la langue source alors que le reste du site est traduit
- Une chaîne apparaît correctement dans WPML String Translation mais ne se traduit jamais sur le site
- Un texte injecté en JavaScript, message de validation ou notification, ne passe jamais par la traduction
- Les traductions personnalisées ont disparu après une mise à jour du thème ou de l’extension
- L’ajout d’une nouvelle langue révèle d’un coup une dizaine de chaînes jamais traduites

## Pourquoi une chaîne reste intraduite

Un site WordPress multilingue s’appuie généralement sur WPML ou Polylang, deux extensions qui traduisent les chaînes enregistrées via les fonctions gettext de WordPress — __(), _e(), esc_html__() — et rattachées au text domain du thème ou de l’extension concernée. Si une chaîne n’apparaît jamais dans l’outil de traduction, c’est d’abord qu’elle n’est pas traduisible structurellement : écrite en dur dans un fichier PHP ou un template, sans passer par gettext.

Le deuxième cas fréquent : la chaîne existe en tant que texte traduisible, mais le text domain n’est pas chargé correctement, par exemple parce que load_plugin_textdomain() est absent ou pointe vers le mauvais dossier /languages. Les fichiers .po et .mo existent, mais WordPress ne va jamais les chercher.

Le module String Translation de WPML ne trouve que ce qui a été correctement enregistré : une chaîne injectée en JavaScript, ou construite par concaténation en PHP plutôt que passée entière à gettext, échappe au scan.

## Traduire quelques chaînes n’est pas corriger du code

> Enregistrer et traduire une poignée de chaînes déjà traduisibles se fait en configuration, directement dans WPML ou Polylang. Rendre traduisible un texte codé en dur dans le thème ou une extension demande de modifier le code source pour qu’il passe par les fonctions gettext : c’est du développement.

## Pages liées

- **Extension sur mesure** — Rendre un texte codé en dur réellement traduisible demande de modifier le code source. ([/wordpress-woocommerce/extension-sur-mesure](/wordpress-woocommerce/extension-sur-mesure))
- **Produits invisibles dans la boutique** — Une traduction WPML non liée à l’original peut aussi rendre un produit invisible dans une langue. ([/wordpress-woocommerce/problemes/produits-invisibles-boutique](/wordpress-woocommerce/problemes/produits-invisibles-boutique))
- **Maintenance WordPress** — Un suivi après chaque mise à jour évite de perdre des traductions personnalisées. ([/services/maintenance](/services/maintenance))

## FAQ

### Pourquoi certaines chaînes n’apparaissent-elles jamais dans WPML String Translation ?

Parce qu’elles ne sont pas enregistrées comme traduisibles dans le code : une chaîne codée en dur dans un fichier PHP, ou construite par concaténation, n’est jamais scannée par WPML. Il faut d’abord corriger le code pour qu’elle passe par une fonction gettext.

### J’utilise Polylang plutôt que WPML, est-ce que ça change quelque chose ?

Le principe est le même : les deux s’appuient sur les fonctions gettext de WordPress et sur un text domain correctement chargé. Seuls l’interface de traduction et le mode de stockage diffèrent.

### Une mise à jour de mon thème a effacé des traductions que j’avais faites, pourquoi ?

Ça dépend de la façon dont l’extension de traduction stocke ces chaînes : certaines méthodes de stockage sont écrasées par une mise à jour qui régénère les fichiers de langue source. Je vérifie ce mécanisme avant de corriger quoi que ce soit.

### Combien de temps pour traduire les chaînes manquantes ?

Pour des chaînes déjà traduisibles, c’est rapide, souvent quelques heures. Rendre traduisible du texte codé en dur dépend du nombre de fichiers concernés.

### Le texte apparaît bien traduit en prévisualisation mais pas sur le site public, pourquoi ?

Souvent un problème de cache : une page mise en cache avant l’enregistrement de la traduction continue d’afficher l’ancienne version tant que le cache n’est pas vidé.
