Formation « Créer des blocs avec Gutenberg »

i18n : internationaliser le Javascript de Gutenberg

Lecture : 4 minutes • 23

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.

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

Conseil

Normalement, si vous avez bien utilisé create-block, vous n’avez rien à faire dans cette première partie : tout est déjà prêt pour la traduction.

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 :

PHP
capitaine-gut-bases.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.

PHP
capitaine-gut-bases.php

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.

JSX

Le premier paramètre est notre chaine, en anglais, et le second est le Text Domain.

Attention

Les textes dans block.json ne sont pas traduisibles. Dans ce cas, déplacez le titre, la description et les mots-clés du bloc dans index.js plutôt.

Pour que ça fonctionne, il faudra bien penser à charger la librairie @wordpress/i18n au début de chaque fichier JS qui utilisera la fonction __() :

JSX

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 :

Installer WP-CLI

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 :

Shell

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.

Le terminal indique que le fichier a bien été généré.
Notre fichier .pot a bien été généré et contient les chaines à traduire

En ouvrant le fichier, vous remarquerez que toutes les chaines de notre extension ont bien été détectées et listées.

Attention

Il faudra relancer la commande make-pot lorsque vous ajouterez de nouvelles chaines de texte dans votre extension, afin qu’elles soient prises en compte dans votre catalogue.

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 :

Loco Translate

Loco Translate

Traduisez directement des thèmes et extensions WordPress depuis votre navigateur.

Par Tim Whitlock

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.

L'interface de traduction des chaines de l'extension Loco Translate
L’interface de traduction de Loco

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.

le dossier languages contient les fichiers de traduction en français générés par Loco Translate
Les fichiers ont bien été générés

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 :

Shell

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.

Les textes apparaissent désormais en français dans vos blocs
Vos blocs sont désormais 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 !

23

Questions, réponses et commentaires

  1. 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?

    1. 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

      1. 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.

        1. 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.

  2. 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’ );
    }

    1. 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.

      1. 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.

        1. 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.

  3. 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 !

    1. 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.

  4. 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. 🙁

    1. 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 ?

      1. 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.

      2. 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.

        1. 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.

  5. 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.

  6. 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 !

    1. 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.

      1. Thanh

        Le 3 mars 2023

        Merci beaucoup, je vais refaire une passe alors 🙂

  7. 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 ?

    1. 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.

  8. Joffrey

    Le 2 septembre 2023

    De mon côté j’ai rencontré un problème un peu bizarre, la traduction de mes blocs ne fonctionnait pas.

    J’ai fait plusieurs erreurs :
    – générer le fichier .pot à partir de PoEdit
    – je n’avais pas déclaré `wp_set_script_translations` pour chaque bloc

    Problème rencontré : la commande `wp i18n make-json` générait 2 fichiers json pour chacun de mes bloc.
    En fait cette commande créait un fichier différent pour chaque fichier js contenant des chaines à traduire.
    En comparant les hash générés, j’ai pu déterminer qu’ils correspondaient au fichiers suivant pour chacun de mes blocs :
    `./src/block-name/index.js` et `./src/block-name/edit.js`

    Du coup WP ne pouvait pas afficher mes traductions car il cherchait un fichier .json avec un hash correspondant au fichier `./build/block-name/index.js`

    Bref, mes conseils pour faire en sorte que ça marche si vous avez des soucis :

    **N’UTILISEZ PAS PoEdit pour créer votre fichier textdomain.pot**
    **Excluez le répertoire `./src` lorsque vous créez le fichier `.pot`**

    1) Créez le fichier .pot à partir de la commande `wp i18n make-pot` et excluez le répertoire `./src`
    Exemple : `wp i18n make-pot ./ ./languages/textdomain-blocks.pot –exclude=’src’`

    2) Mettez à jour vos fichiers .po à partir du fichier `textdomain-blocks.pot` que vous venez de créer (vous pouvez utiliser PoEdit ici)

    3) Passez en revue / mettez à jour les traductions dans vos fichiers .po

    4) Supprimez tous les fichiers de traduction .json du répertoire de langue de votre plugin/thème

    5) Exécutez la commande `wp i18n make-json textdomain-fr_FR.po –no-purge`

    6) Dans votre code, assurez-vous d’appeler la fonction `wp_set_script_translations` pour chaque bloc que vous avez avec le bon handle : block name (‘name’) dans le fichier block.json où il faut remplacer le `/` par `-`.
    Vous pouvez utiliser cette fonction pour le faire : `generate_block_asset_handle( ‘textdomain/mon-bloc-1’ );` donnera ‘textdomain-mon-bloc-1’ à utiliser dans la fontion `wp_set_script_translations`
    Exemple :
    wp_set_script_translations( ‘textdomain-mon-bloc-1’, ‘textdomain’, plugin_dir_path( __FILE__ ) . ‘languages’ );
    wp_set_script_translations( ‘textdomain-mon-bloc-2’, ‘textdomain’, plugin_dir_path( __FILE__ ) . ‘languages’ );

    Les traductions devraient fonctionner.

    1. Maxime BJ

      Le 3 septembre 2023

      Merci pour ta contribution. Il faut que je revois ce cours en effet, ça doit être plus stable aujourd’hui pour les traductions. C’était encore un peu chaotique à l’époque où j’ai écris ces cours.

Laisser un commentaire