Drupal 8 – Comment traduire la Config API

Auteur(s) de l'article

Je vis en Suisse et ce pays possède une singularité surprenante: il possède 4 langues nationales (n'oublions pas sempiternellement le Romanche), et plus de 90% de nos créations web nécessitent d’être localisées dans au moins 2 langues.
Cette particularité linguistique nous a permis de devenir des experts dans la création de sites web multilingues, et ça tombe bien puisque c'est exactement l’un de ces aspects que nous allons traiter dans les prochaines lignes.
Lors de la création d'application avec Drupal 8, nous sommes souvent confrontés à la création de formulaires de configuration contenant des données administrables par nos clients. Le cas le plus concret est - par exemple - les liens des réseaux sociaux qui doivent être différents selon la langue du site.
La suite de ce blogpost va vous exposer comment activer le système de traduction des configurations via un formulaire ConfigFormBase.
Nous allons passer au travers de la création de structure par la génération du schéma ainsi que par l'activation à proprement parler du système de traduction.

Les pré-requis

Every solution to every problem is simple. It's the distance between the two where the mystery lies.

Derek Landy

Skulduggery Pleasant

Si vous ne connaissez pas encore le système de Config API de Drupal 8, je vous laisse découvrir l'article Drupal 8 - Differences between Configuration API & State API traitant d'un point de vue global le sujet. Vous pouvez également trouver une aide plus complète et fournie directement avec la documentation officielle.
Cet article s'adresse à des développeurs Drupal 8 avertis.

Les assets

Give me matter and I will build a world out of it.

Immanuel Kant

Avant de vous expliquer comment tout cela fonctionne, vous pouvez récupérer l'ensemble des fichiers d'exemples ci-dessous.
L'ensemble de cet article est testable via le module de tests téléchargeables ici.
Pour aider à la compréhension de cet article, 2 formulaires de configuration avec traductions vont vous être présentés et utilisés dans nos différents exemples:
  1. Le premier étant un formulaire simple sans spécialité, démontrant le système de traductions de plusieurs types de champs tels que:
    • Texte simple - traduisible
    • Select - non traduisible
    • Checkbox - non traduisible
    • Checkboxes - non traduisible
    • Radios - non traduisible
    • Textarea - traduisible
    • CKeditor - traduisible
  1. Le second étant un formulaire complexe, démontrant le système de traductions via mapping et sauvegarde de structure en séquence:
    • Champs imbriqués sous plusieurs niveaux - traduisible
    • Entity reference - non traduisible
    • Textarea avec preprocess en séquence (stockage en tableau) - traduisible
Comme vous l’aurez certainement remarqué, plusieurs champs sont “non-traduisibles”. Ce n’est pas un choix délibéré de ma part, mais le Core Drupal m’y force, et c’est bien normal ! Si on s’y attarde quelques instants, les champs qui ne sont pas traduisibles sont des champs dits “clé” -> “valeur”. Il est donc normal de ne pas pouvoir traduire des clés puisqu’elles correspondent à votre propre Business Logic. Quant aux valeurs, elles sont traduisibles via la fonction de traduction standard exposée par le Core.

Définition des valeurs par défaut

La structure est un fichier différent par configuration, ici nous allons en avoir 2 puisque nous avons 2 configurations distinctes:
  • SettingsForm -> my_module.settings.yml
  • SettingsAdvancedForm -> my_module.settings_advanced.yml
Ces fichiers de structure se retrouvent toujours dans le dossier config/install du module. Ils correspondent à l'initialisation de la configuration, soit les valeurs par défaut. Ces fichiers ne sont pas obligatoires par défaut dans Drupal 8, mais le deviennent une fois que nous voulons rendre notre configuration traduisible.
Ces fichiers doivent être nommés de manière bien spécifique, soit selon le nom de la configuration correspondante. Vous retrouvez ce nom dans l'array de la méthode getEditableConfigNames de vos formulaires de configuration.
Voyons à quoi ressemble la définition de la structure de nos 2 formulaires ci-dessus:
SettingsForm
SettingsAdvancedForm
Si l'on regarde de plus près ces 2 fichiers, nous remarquons qu'ils correspondent à ce que nous sauvegardons en base de données. L'ensemble des champs sauvegardés en base de données doit s'y retrouver. De plus, la structure de votre configuration est également représentée dans ce fichier.
SettingsForm
title: ''                # Le champ texte simple
select: ''               # Le champ select
checkbox: FALSE          # Le champ boolean checkbox
checkboxes: { }          # le tableau des checkboxes
radios: ''               # la valeur sélectionner parmis les radios
message: ''              # le contenu du textearea
ckeditor:
  value: ''              # le contenu du ckeditor
  format: 'basic_html'   # le type de format utilisé
SettingsAdvancedForm
site:                   # Tableau contenant nos data
  title: ''             # Le champ texte simple (noté l'indentation)
  content:
    value: ''           # le contenu du ckeditor
    format: basic_html  # le type de format utilisé
mails: { }              # la valeurs, sous forme de tableau, provenant du textarea
entity_reference: ''    # l'entité référencée

Définition du schéma

Le schéma est un fichier unique, quel que soit le nombre de configurations dont votre module dépend. Dans ce fichier, nous retrouvons nos arbres de structures correspondants à l’étape précédente, mais cette fois-ci nous ajoutons pour chaque clé non plus sa valeur par défaut, mais son type et un label.
CheatSheet des formats et types utilisables dans un schema.yml Drupal 8.
CheatSheet des formats et types utilisables dans un schema.yml Drupal 8.
Grâce à l'application de ce schéma sur votre configuration, nous pouvons dire quelle clé est traduisible et quel est son Label dans l'interface de traduction des configurations !
Vous vous demandez pourquoi nous devons fournir un schéma complet alors que nous n’utilisons pas toutes les clés pour la traduction ? Et bien le schéma n'est pas utilisé uniquement pour les traductions ! Par exemple, lorsque vous éditez une configuration, les formulaires vont utiliser le schéma afin de “type-caster" les données. Ceci permet d'assurer qu'un champ défini comme booléen dans votre schéma soit bien un booléen et non un string lors de la manipulation des configs. De plus, ce fichier est utilisé pour la génération automatique du formulaire de traduction, d'où la nécessité d'ajouter un Label à chaque clé.
Le schéma doit être créé directement dans le dossier config/schema et doit être nommé selon le nom du module: my_module.schema.yml.
Voici à quoi ressemble le schéma de configuration de nos 2 formulaires:
En somme, le système de schéma, tout comme le fichier de structure, est optionnel tant que vous n'avez pas besoin de traduire votre configuration.

Activation de la traduction

Une fois que vous avez créé votre fichier de structure et votre fichier de schéma, il ne vous rester plus qu'à déclarer au système de traduction des configurations quels sont les formulaires qui exposent des traductions.
Pour ceci, il vous suffit de créer le ficher my_module.config_translation.yml.
Ce fichier contient l'ensemble des formulaires de configuration exposant des traductions. Chaque formulaire doit définir un titre, la route d'accès au formulaire et enfin l'ensemble des clés de configurations qu'il expose.
Vous pouvez désormais accéder aux formulaires de traductions depuis l'entrée : Configuration > Regional and language > Configuration translation.

Ajouter une tab de traduction

Maintenant que votre formulaire est traduisible, il est parfois déconcertant de devoir se rendre sur la page "Configuration translation”, cachée derrière 3 niveaux de lien et il serait bien plus pratique d'accéder à cette page depuis une “Local task”, comme le proposent les autres fonctionnalités du Core Drupal 8.
Local task de traduction pour le formulaire Core - Basic Site.
Local task de traduction pour le formulaire Core - Basic Site.
Par défaut, le système de traduction va générer une "Local task” - soit une tab - pour les traductions de votre formulaire. Cependant il se peut que vous ne la voyiez pas. En effet, pour voir cette action il faut que votre formulaire expose lui même au moins 1 "Local task”. Avouez que c'est un peu tiré par les cheveux, mais voici comment y remédier en créant au moins une “Local task” sur votre propre formulaire.
  1. Créez une nouvelle "Local task” dans votre module à l'aide du fichier my_module.links.task.yml se trouvant à la racine de votre module.
  2. Ajoutez une entrée par formulaire de configuration exposant des traductions.

Sources

Pour les plus curieux d'entre vous, voici quelques sources d'informations complémentaires ayant inspiré la création de cet article.
Gábor Hojtsy (29 october 2015). Configuration translation development. Retrieved from hojtsy.hu
Alex Tkachev (16 décembre 2014). Drupal 8 configuration management.
Retrieved from amazeelabs.com