Dans ce cours on va voir comment gérer l’internationalisation de nos chaines de texte en PHP et en JS afin que nos blocs puissent être traduits dans toutes les langues.
Sommaire du cours
Afin de rendre notre extension traduisible dans toutes les langues possibles, il y a quelques manipulations supplémentaires à faire, comme détecter les chaines, générer le catalogue de traduction et enfin traduire les chaines.
On va également voir que la manipulation n’est pas identique selon que vous souhaitez faire de votre extension : la publier sur wordpress.org, ou alors la garder privée ou la rendre premium.
Déclarer le textdomain et les traductions en PHP
Dans chaque projet WordPress, que ce soit un thème ou une extension, il faut déclarer un Text Domain : C’est l’identifiant unique de nos chaines de traduction.
Dans notre cas, il est déclaré dans les données du plugin, au début du fichier PHP :
On peut remarquer que le textdomain correspond au nom de dossier de notre extension, dans mon cas : capitainewp-gut-bases
.
Le saviez-vous ?
Le text domain permet de distinguer les traductions du coeur, des extensions et thèmes. Cela vous permet d’éviter les conflits avec une chaine qui serait la même dans une autre extension, mais dont la traduction serait différente.
Comme notre extension est faite en majorité à base de Javascript, il va falloir envoyer ces traductions de PHP à JS, et pour cela WordPress possède une fonction dédiée à cette tâche. C’est wp_set_script_translations()
que l’on va utiliser dans l’action init
.
Du coup, tout est paré côté PHP.
Utiliser les fonctions d’internationalisation en JS
Côté Javascript maintenant, on va avoir accès à la fonction __()
qui va nous permettre de rendre nos chaines traduisibles. Et si vous avez suivi toute la formation, vous avez vu qu’on a déjà préparé toutes nos chaines en vue d’une traduction.
Le premier paramètre est notre chaine, en anglais, et le second est le Text Domain.
Pour que ça fonctionne, il faudra bien penser à charger la librairie @wordpress/i18n
au début de chaque fichier JS qui utilisera la fonction __()
:
Pour en savoir plus sur l’internationalisation des chaines dans WordPress, consultez mon cours sur l’i18n. Et pour en savoir plus sur l’internationalisation d’extensions, consultez la documentation officielle en ligne.
Le saviez-vous ?
i18n veut dire internationalization : il y a 18 lettres entre le premier i et le dernier n.
Tout est prêt, on va maintenant pouvoir passer à la suite, et il existe 2 cas :
Générer le catalogue .POT de traduction avec WP-CLI
On va devoir maintenant générer le catalogue de traduction, sous la forme d’un fichier .pot
que l’on stockera dans le dossier languages
.
Ce fichier servira de base pour créer des traductions dans toutes les langues, via des fichier .po
et .mo
que l’on traduira à l’aide de Loco Translate ou POedit.
Pour créer notre catalogue, on va utiliser WP-CLI qui permet de faire des actions avec WordPress en ligne de commande.
Installer WP-CLI
Si vous n’avez pas WP-CLI sur votre système, voici comment l’installer :
Si vous voulez en savoir plus, voici le lien vers le Handbook WP-CLI officiel.
Générer le catalogue .pot
Maintenant, à partir du dossier de notre plugin, on va créer un sous-dossier languages, et générer le catalogue à l’intérieur via ces commandes :
Pensez-bien à donner le même nom de fichier que le Text Domain, et qui devrait être du coup le même que le nom du dossier de l’extension.
Si tout s’est bien passé, votre terminal vous indique que la manoeuvre a bien fonctionné, et devriez avoir un nouveau dossier languages
qui contient votre fichier .pot
.
En ouvrant le fichier, vous remarquerez que toutes les chaines de notre extension ont bien été détectées et listées.
C’est donc tout bon, on va pouvoir commencer la traduction.
Lancer une traduction via Loco Translate
Il existe plusieurs solutions pour lancer des traductions, et les développeurs utilisent en général le logiciel POEdit.
Mais vous pouvez également utiliser une extension directement dans votre site qui s’appelle Loco Translate et qui fait le travail tout aussi bien :
Une fois installée et activée, allez dans Loco Translate > Extension > Votre extension.
On arrivera sur une interface qui ne liste aucune traduction pour le moment. C’est normal. Cliquez sur Nouvelle langue et choisissez Français.
Laissez l’emplacement auteur : on veut enregistrer la traduction dans le dossier de notre extension, afin de la versionner par la suite.
Maintenant, il faut traduire chaque chaine. Pensez à cliquer sur Enregistrer une fois que c’est fait.
Vous verrez alors un fichier .po
et un .mo
en FR dans votre dossier languages.
Vous apercevrez aussi des fichiers json qui ont été générés par la commande make-pot
.
Le saviez-vous ?
Le fichier MO est la version binaire compilée du fichier PO. C’est le MO qui est utilisé par PHP car plus rapide à exécuter pour le script.
Par contre, on utilise le fichier PO via Loco pour éditer les traductions. Ce dernier s’occupe ensuite de la compilation.
Générer les fichiers JSON
Et enfin, il va falloir générer les fichiers JSON correspondants. Pour cela, il suffit de lancer une dernière commande depuis le terminal :
Il faudra le faire pour chaque fichier .po
dans chaque langue.
Maintenant, essayez d’utiliser l’un de vos blocs afin de contrôler que les chaines apparaissent désormais bien en français.
Et voilà c’est parfait !
Voilà pour l’internationalisation de Gutenberg. Votre extension est désormais prête pour être traduite dans tous les langues !
David Dufour
Le 29 avril 2021
J’ai fait tout ça. Ceci a généré un fichier json par bloc (J’en ai 2) et j’ajoute wp_set_script_translations pour chaque bloc. Cependant, ma traduction ne fonctionne pas plus. Une idée?
Maxime BJ
Le 29 avril 2021
Normalement, tu ne devrais avoir qu’un seul wp_set_script_translations dans ton extension. Vérifie que tu as bien un fichier dans /build/index.asset.php
David Dufour
Le 30 avril 2021
Même si j’ai plusieurs fichiers de blocs. La commande qui génère des fichiers json pour les langues a créé 2 fichiers. Et on doit passer le $handle
(string) (Required) Script handle the textdomain will be attached to.
Maxime BJ
Le 30 avril 2021
Oui car au final il n’y a qu’un seul script compilé à la fin pour l’ensemble de tes blocs, donc un seul appel aux traductions. Ensuite, il ira chercher le bon json en fonction du bon bloc et de la langue.
David Dufour
Le 30 avril 2021
Voici mon code avec la modification que tu as parlé:
function register_scripts_block_editor_assets(){
if ( ! function_exists( ‘register_block_type’ ) ) {
// Gutenberg is not active.
return;
}
$dir = CHACHA_FOLDER . ‘/assets/js/blocks/’;
$blocks = array_filter( glob( $dir.’*’ ), ‘is_file’ );
foreach( $blocks as $block ){
$type = str_replace( $dir, ”, $block );
$type = str_replace( ‘.js’, ”, $type );
wp_enqueue_script(
$type,
plugins_url( ‘/assets/js/blocks/’.$type.’.js’, CHACHA_FILE ),
[ ‘wp-edit-post’, ‘wp-i18n’ ],
CHACHA_VERSION
);
}
// Add language json file to script
wp_set_script_translations( ‘column’, ‘chacha-gutenberg’, plugin_dir_path( __FILE__ ) . ‘lang’ );
}
Maxime BJ
Le 30 avril 2021
En fait, tu ne dois pas toucher le reste du code (généré par create-block) en dehors du paramètre que j’ajoute dans wp_set_script_translation. Le reste est déjà bon et fonctionnel de base.
David Dufour
Le 30 avril 2021
Tu as un moyen qu’on puisse se parler plus efficacement?
Btw, j’apprécie énormément ton aide. Nous sommes nouveau sur Gutenberg et nous aimons beaucoup le concept.
Maxime BJ
Le 30 avril 2021
J’ai fait un channel #capitainewp sur le slack WordPress FR si jamais. Je ne suis pas hyper dispo en ce moment mais ce sera plus simple pour partager ton code. Essaie de voir si la traduction fonctionne avec mon plugin de ressources (dispo en début de formation) car j’avais fait la bonne config et tu devrais pouvoir comparer pour voir où ça plante.
Pierre Lejeune
Le 13 mai 2022
Bonjour capitaine,
Afin d’améliorer un plug-in de blocs customisés Gutenberg, je me suis penché sur l’internationalisation de contenu en suivant ton article.
Tout fonctionne à merveille mais je m’interroge sur la commande que tu partages en fin d’article : “wp i18n make-json capitainewp-gut-bases-fr_FR.po –no-purge”… Il ne manque pas un tiret à l’option “-no-purge” ?
WP-CLI ne reconnaît pas “-no-purge” comme option de commande, mais comme argument pour le répertoire de destination, ce qui est particulièrement gênant puisque non seulement, le fichier de destination n’a pas/peu de sémantique, mais en plus le fichier “.po” est “purgé”.
Pour le reste, rien à redire ! Je te remercie pour tes contenus de qualités !
Maxime BJ
Le 13 mai 2022
Oui en effet, c’est bien un double tiret qu’il faut mettre. C’est ce que j’ai mis dans l’éditeur, mais pour une raison obscure l’un d’entre-eux est supprimé à l’affichage en front.
Romain
Le 27 octobre 2022
En créant avec guten-block, il y a une erreur sur le handle du Script dans le tuto. Ce n’est pas // slug du plugin suivi de block-editor mais suivi de -editor-script.
Après j’ai les étapes décrites, j’arrive à entrer des traductions pour le script, mais ça n’affiche pas les traductions. 🙁
Romain
Le 27 octobre 2022
Le gros problème, c’est que Loco translate, comme la ligne de commande, ne ciblent pas le fichier .js sorti par le processus de transcompilation. Au lieu de ça ils pointent vers les sources, lesquelles ne sont jamais chargées. Que faire ?
Maxime BJ
Le 30 octobre 2022
Avant de générer le .js, tu vas générer le .pot, c’est lui qu’il faut regarder pour voir toutes les chaines. Tu peux utiliser POEdit si Loco ne fait pas l’affaire.
Romain
Le 27 octobre 2022
Du coup, la seule solution qui a abouti est de réunir les fichiers json en seul, et de remplacer le md5 par le handle du script compilé. Le hook est ici. https://localise.biz/wordpress/plugin/hooks/loco_compile_single_json
Maintenant, j’aimerai vraiment beaucoup comprendre la méthode qui semble standard.
Qu’est-ce qu’il faut faire pour que wp_set_script_translations envoie bien les fichiers de traduction au script?
Le répertoire des langues est le bon, les fichiers .json sont là mais rien ne charge.
Maxime BJ
Le 30 octobre 2022
Avec la technique officielle, tu n’as pas besoin de solutions tierces pour t’en sortir. Certes c’est un peu complexe et un peu chiant, mais ça doit fonctionner si tu suis bien toutes les étapes.
Klemart3D
Le 23 novembre 2022
Par défaut, l’installation de wp-cli par un gestionnaire de paquet (type brew sur macOS) installe la dernière version de php (8.1 à ce jour) mais l’exécution de la commande de traduction génère des erreurs de ce type :
`Deprecated: preg_split(): Passing null to parameter #3 ($limit) of type int is deprecated` ou `Parse error: syntax error, unexpected fully qualified name “\Syntax\Node\Expression”, expecting “,” or “;”`
En repassant sur une version php antérieure (ex 7.4) cela fonctionne correctement.
Thanh
Le 1 mars 2023
Hello,
j’ai refait la manipulation plusieurs fois, et rien n’y fait. Mon interface n’est pas traduite une fois que j’ai passé l’étape de génération des JSON.
Dans d’autres tuto sur le net, il est parfois question de faire appel à la fonction load_plugin_textdomain();
Est-qu’il existe un dépôt github pour voir l’ensemble des fichiers du plugins ?
Merci !
Maxime BJ
Le 1 mars 2023
Il se peut qu’il y ait eu (encore) des changements de ce côté là. Je t’invite à regarder la documentation officielle pour voir s’ils expliquent autre chose : https://developer.wordpress.org/block-editor/how-to-guides/internationalization/.
Mais on est d’accord, c’est pas aussi simple que ça le devrait.
Thanh
Le 3 mars 2023
Merci beaucoup, je vais refaire une passe alors 🙂
Valentin
Le 27 avril 2023
Bonjour,
après avoir suivit la formation, j’essaie depuis quelque jours de traduire le plugin de block gutenberg. J’ai repris ton dépôt github, ajouté les quelques lignes appelant la fonction wp_set_script_translations() et j’ai traduit quelques chaines avec loco-translate. J’arrive à traduire les termes PHP mais ceux dans les fichiers (index, edit, save) ne se traduisent pas. J’ai vu que loco-translate génère beaucoup de fichiers .json, je ne sais pas si ça pose problème. As tu une idée de pourquoi la traduction n’est pas prise en compte dans le plugin ?
Maxime BJ
Le 27 avril 2023
Peut-être que la procédure officielle a changé (ça change souvent, c’est dur à suivre). Dans le précédent commentaire, j’ai mis le lien vers la documentation officielle. Il y aura peut-être un indice. En tous cas c’est normal qu’il y ait beaucoup de fichiers json générés oui. C’est comme ça que sont livrées les traductions en JS.