Niveau Niveau confirmé

Traduire vos extensions WordPress

Tutorieldéveloppement

Publié par le , mis à jour le (5040 lectures)

wordpress i18n langue international

Pour ce dernier article de 2021 (et pour ne pas vous prendre trop de temps pendant les préparatifs des fêtes de fin d'année 😉), voici un complément au sujet précédent, qui portera cette fois sur l'internationalisation des extensions dans l'écosystème de WordPress.

⚠ Si vous ne l'avez pas déjà fait, nous vous invitons vraiment à lire l'article Préparer un thème WordPress pour l'internationalisation. Les outils et concepts sont les mêmes pour les thèmes et les extensions et nous ne les réexpliquerons pas ici.

Les extensions indispensables

On commence directement avec un petit cas particulier.

Utilisez-vous les mu-plugins (Must-Use plugins) ?

Ces extensions un peu spéciales sont toujours activées et ne peuvent pas être désactivées autrement qu'en supprimant leurs fichiers sources (vous pouvez les retrouver dans la section "Indispensables" de l'administration des extensions). Pratique pour éviter les erreurs humaines, comme une suppression maladroite par exemple... 🤫

Sans rentrer dans les détails, il est tout à fait possible d'y inclure des textes et il faut donc penser à les rendre traduisibles. Pour se faire, utilisez la fonction load_muplugin_textdomain de la manière suivante :

/**
 * Chargement des fichiers de traductions dans le dossier /lang
 */
function load_translations() {
  load_muplugin_textdomain( 'textdomain', 'lang' );
}
add_action( 'muplugins_loaded', 'load_translations' );

Ici, on part du principe qu'un dossier /lang a été rajouté au dossier mu-plugins de WordPress.

On utilise le hook muplugins_loaded pour que les traductions soient chargées le plus tard possible, de la même manière que l'on utilise after_setup_theme pour charger les fichiers de traductions d'un thème.

Si vous voulez en apprendre davantage sur les mu-plugins, consultez l'article Connaissez-vous les MU Plugins de WordPress ? qui explique les bases et donne des exemples concrets de cas d'utilisation.

Et pour les extensions plus classiques ?

Avant de nous lancer dans le coeur du sujet, commençons par quelques rappels de conventions et conseils de base.

1/ Toutes les chaines de caractères doivent être accompagnées d'un domaine de traductions.

Seul le coeur de WordPress utilise des traductions du type __( 'Settings' ) et même s'il peut être tentant de réutiliser ces chaines si votre extension les partage, il n'est pas impossible qu'une une mise à jour les change, rendant ainsi votre chaîne intraduisble.

2/ Les textes à traduire doivent avoir un sens et un contexte.

Évitez de faire de la concaténation de mots et préférez des phrases entières.

3/ N'utilisez pas de variables directement dans des appels à __().

Si besoin d'insérer du HTML ou des données, entourez vos fonctions de printf ou sprintf pour pouvoir utiliser des placeholders selon ce genre de modèle

sprintf(
  __( 'Bonjour %s', 'textdomain' ),
  $username
);

4/ N'oubliez pas de renseigner les commentaires d'entêtes de votre extension !

/*
 * Plugin Name: Mon extension à moi !
 * Author: (La loi) C'est moi !
 * Text Domain: text-domain
 * Domain Path: /lang
 */

Les 2 informations qui nous intéressent ici sont Text Domain et Domain Path (notez bien les majuscules, elles sont importantes).
Elles permettent respectivement d'indiquer à WordPress votre domaine de traduction ainsi que l'emplacement de vos fichiers de traductions et ce, même si votre extension est désactivée !

Ce ne sont évidemment pas les seuls points de vigilance, mais s'attarder davantage ici ne ferait que paraphraser la documentation officielle, qui est déjà bien assez complète.

Maintenant que ces quelques détails ont été abordés, nous pouvons enfin passer au chargement de vos précieuses traductions ! 😉 L'avantage est que la procédure reste exactement la même. Seule la fonction utilisée change.

/**
 * Chargement des fichiers de traductions dans le dossier /lang
 */
function load_translations() {
  load_plugin_textdomain( 'textdomain', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' );
}
add_action( 'init', 'load_translations' );

On évitera d'utiliser le hook plugins_loaded, qui arrive trop tôt dans le cycle de vie de WordPress et pourrait créer des conflits avec les traitements appliqués par d'autres scripts.

Note : Depuis WordPress 4.6, load_muplugin_textdomain et load_plugin_textdomain tenteront d'abord de charger les fichiers de traductions depuis le dossier /languages de WordPress, donc si vous le voulez, vous pouvez les y mettre directement.

Utiliser des traductions dans des fichiers JavaScript

Vous savez dorénavant comment utiliser vos fichiers .po et .mo dans vos extensions. Il ne nous reste donc qu'un dernier sujet à couvrir : comment utiliser vos traductions dans vos fichiers JS.

Fort heureusement, WordPress met à disposition une fonction à cet effet répondant au doux nom de wp_localize_script et dont les 3 paramètres (tous requis) sont les suivants :

  1. $handle, qui correspond au nom donné au script auquel vous souhaitez transmettre des chaines de caractères (le "nom" du script fait référence au premier paramètre des fonctions wp_register_script ou wp_enqueue_script).
  2. $object_name. Tout simplement le nom de la variable JS qui sera injectée par WordPress.
  3. $l10n, un tableau clé/valeur des traductions que vous voulez rendre disponibles dans votre fichier JS.

Voici un exemple de code pour un script nommé script-kiwi auquel on voudrait passer plusieurs traductions.

/**
 * Chargement des scripts de l'extension
 */
function plugin_scripts() {
  wp_enqueue_script( 'script-kiwi', ... );
  wp_localize_script( 'script-kiwi', 'mon_super_objet',
    array( 
      'chaine_1' => __( 'Ma super traduction', 'textdomain' ),
      'chaine_2' => __( 'Mon autre super traduction', 'textdomain' ),
      'chaine_3' => __( 'Une traduction encore mieux que les autres', 'textdomain' ),
    )
  );
}
add_action( 'wp_enqueue_scripts', 'plugin_scripts' );

Et voilà ! 🎉

Dorénavant, WordPress mettra à disposition une variable globale mon_super_objet que l'on peut utiliser comme un objet JavaScript standard pour en extraire les propriétés. Ainsi, mon_super_objet.chaine_1 affichera la chaine "Ma super traduction" dans la langue souhaitée.

Cette fonction ne peut être utilisée que si votre script a déjà été ajouté via wp_register_script ou wp_enqueue_script.

Un dernier pour la route

Le dernier point de vigilance auquel prêter attention est la mise à jour de vos propres extensions.

Il est assez fréquent de faire évoluer ses extensions pour y inclure de nouvelles fonctionnalités, refactoriser du code qui commence à se faire vieux ou plus simplement rajouter des commentaires pour expliquer à quoi sert la fonction doEverything() de votre extension maison.

Tous ces exemples ont en commun que l'emplacement physique de vos chaines de traductions (les lignes dans votre fichier) peut ne plus être le même en passant de la version X à la version Y et si vous ne régénérez pas vos fichiers .pot, .po et .mo, vous courrez droit à la catastrophe !

Un exemple bien senti venant directement du fichier .po de Polylang.

#: modules/wizard/view-wizard-step-last.php:26
#: modules/wizard/view-wizard-step-last.php:44
msgid "Read documentation"
msgstr "Lire la documentation"

Les nombres en fin de ligne correspondent à la ligne du fichier dans lequel on retrouve la chaine en question. A partir de là, il est facile de comprendre que si une chaine bouge, elle ne sera plus reconnue, ce qui serait dommage après tous ces efforts.

Pour cela, une règle simple : si une chaine change de ligne, il faut le refléter dans vos fichiers de traductions.

Conclusion

Comme promis, rien de bien méchant si vous avez survécu à la lecture du premier article.

Maintenant, vous n'avez plus aucune excuse pour ne pas internationaliser tout ce qui bouge dans vos développements WordPress !

Bonnes fêtes de fin d'année à toutes et tous ! 🎅🎄

Commenter

Vous devez être inscrit et identifié pour utiliser cette fonction.

Connectez-vous (déjà inscrit)

Oubli de mot de passe ? Pas de panique, on va le retrouver

Pas encore inscrit ? C'est très simple et gratuit.