Fil d'Ariane
Drupal 10 : CMI / Configuration, les fondements
L'industrialisation s'invite dans le cœur de Drupal !
Cet article a été initialement rédigé pour Drupal 8 mais son contenu est toujours d'actualité pour Drupal 9 et Drupal 10.
N'hésitez pas à nous contacter ou à vous inscrire à notre formation «Drupal pour les développeurs et développeuses» pour en savoir plus !
Il y a plusieurs mois de cela nous vous avions présenté les concepts de l'initiative CMI (Configuration Management Initiative) et vous avions montré quelques exemples pratiques. Cette initiative, annoncée dès le démarrage du cycle de développement de Drupal 8. a donné naissance à l’API de configuration. Elle permet l’export de la configuration du site dans des fichiers YAML.
Le YAML
Le YAML est un format de représentation des données standard utilisé par beaucoup d’autres logiciels ou technologies, notamment Symfony. Il a l’avantage d’être plus facilement “parsé” que les anciens fichiers INI en .info tout en restant compréhensible par les humains.
Les fichiers associés à ce format sont les .yml et sont désormais utilisés dans Drupal pour exporter / importer l’ensemble de la configuration du site.
Il existe plusieurs outils pour gérer de la configuration, chacun répondant à un besoin particulier.
- Le Service de gestion de configuration
- La State API
- Les entités de configuration
Les données simples
Les données de configuration simples (exemple : une option oui / non pour un paramètre de votre module, la taille d’un buffer, logger ou non des erreurs, etc) exploitent le Service de gestion de configuration. Ces données très simples à stocker n’ont qu’une version possible et sont pérennes.
Exemple de données simples exportés dans un fichier .yml :
# system.theme.yml
admin: ''
default: stark
Il est possible de fournir de la configuration par défaut, prise en compte lors de l’installation d’un module, en la plaçant dans le dossier config/install/<module_name>.<groupe>.yml du module, le groupe permettant de rassembler des variables traitant du même sujet. Il arrivera que votre module puisse livrer de la configuration pour des dépendances non activées (exemple : une vue pour de la taxonomie alors que le module de taxonomie n’est pas actif). Pour éviter d’avoir à activer tous les modules, vous pourrez livrer de la configuration dite optionnelle, il faudra dans ce cas la placer dans le dossier config/optional/<module>.<groupe>.yml.
Documentation officielle : https://www.drupal.org/node/1809490
Configuration schema
La configuration ayant vocation à être exportée, il a fallut créer une façon de décrire les données à exporter. CMI a mis en place un système de description de la configuration et l’enrichit de certaines méta-données à travers un fichier .yml. L’idée de ce fichier est de décrire le type de données stockées par la configuration, d’y associer un label, d’informer que les données soient traduisibles ou non, etc. Plus d’informations à propos des schémas de configuration et des méta-données peuvent être trouvées sur cette page : https://www.drupal.org/node/1905070.
Le fichier à créer se placera dans config/schema/<module_name>.schema.yml et il permettra de décrire toutes les configurations utilisées par ce module.
Extrait du fichier schéma pour le fichier system.schema.yml :
# system.schema.yml
# [...]
system.theme: # couple .
type: config_object
label: 'Theme settings'
mapping:
admin:
type: string
label: 'Administration theme'
default:
type: string
label: 'Default theme
# [...]
Le couple <module_name>.<groupe> du fichier de configuration sera utilisé comme clef dans le fichier schéma, vient ensuite la description des types de données de chacune des données, ainsi qu’un label descriptif. Les types de données existants sont décrits dans la page de documentation liée plus haut et exploitent la Typed Data API.
Documentation officielle : https://www.drupal.org/node/1905070
Utilisation de la configuration
On pourra récupérer les données liées à ce groupe en utilisant comme identifiant de configuration la clé “module.groupe” (voir ci-dessous).
La configuration doit toujours être sauvée. Mettre des données dans un objet de configuration ne suffit pas. Les objets de configuration peuvent être récupérés soit en lecture seule soit prêts à être modifiés selon les besoins.
# Controller.php
// Récupérer la valeur pour lecture.
$config = \Drupal::config('system.performance');
$enabled = $config->get('cache.page.enabled');
// Définir la valeur pour écriture.
$config = \Drupal::configFactory()->getEditable('system.performance');
$config->set('cache.page.enabled', TRUE);
$config->save();
Une ligne de configuration peut être supprimée en utilisant la fonction clear()
. Pour supprimer une configuration complète il faudra utiliser la fonction delete()
.
Exemple :
# Controller.php
$config_factory = \Drupal::configFactory();
// Supprime la configuration de la durée de vie maximale du cache de page.
$config = $config_factory->getEditable('system.performance');
$config->clear('cache.page.max_age')->save();
// Supprime la configuration globale de system.performance.
$config_factory->getEditable('system.performance')->delete();
Ces données lorsqu’elles sont sauvées sont stockées dans la table config. Cette table remplace la défunte table fourre-tout variable. C’est le point de passage centralisé où les données de configuration transitent avant d’être exportées. Si vos données ne sont pas exportées elles resteront dans cette table.
State API
Certaines de vos données ne seront pas identiques d’un environnement à un autre, voire indépendante. Exemples : dernier passage de cron, clés d’API externe, niveau de reporting des erreurs. Ces données pourraient être éligibles pour être gérées via l’API de configuration des données simples mais un système dédié leur est consacré.
Ce système est la State API qui s’utilise comme suit :
# Controller.php
// Récupérer une valeur.
$maintenance_state = \Drupal::state()->get('system.maintenance_mode');
// Récupérer une valeur multiple.
$pairs = \Drupal::state()->getMultiple($keys);
// Définir une valeur.
\Drupal::state()->set('key','value');
// Définir une valeur multiple.
\Drupal::state()->setMultiple($keyvalues);
// Supprimer une valeur.
\Drupal::state()->delete('key');
Une bonne pratique consiste à préfixer les clés avec le nom du module qui défini la valeur, exemple : system.maintenance_mode. Il n’est pas toujours simple de choisir s’il on va utiliser la State API ou l’API de configuration de données simples alors voici un truc pour savoir quoi faire : si vos données doivent être exportées, utilisez l’API de configuration, si ça n’est pas le cas, la State API fera sûrement l’affaire !
À noter qu'il existe un PDF d'aide pour retrouver toutes les commandes liées à la manipulation de la configuration.
Entité de configuration
Poursuivant le principe de “tout est nœud” puis “tout est entité” des anciennes versions de Drupal, une partie de la configuration se retrouve aussi dans des entités. Cela s’appelle les entités de configuration et elles sont majoritairement utilisées quand il s’agit de définir un ensemble de variables de configuration pouvant être définies plusieurs fois. Le principe de type et de bundle existe dans ce cas là aussi mais les bundles d’entités ne sont pas utilisés. Toutes les entités de configuration d’un même type (une vue, un profil de style d’image, un rôle, un vocabulaire, etc) ont le bundle par défaut. (C’est déjà suffisamment compliqué comme ça !).
Bien qu’ayant un fonctionnement différent des données simples, les entités de configuration sont aussi exportables au même format que la configuration simple.
Exemple de configuration d’une entité exportée dans un fichier .yml :
# user.role.administrator.yml
uuid: aad4152c-be3a-4be7-8555-85d45b67e239
langcode: en
status: true
dependencies: { }
id: administrator
label: Administrator
weight: 2
is_admin: true
permissions: { }
Votre commentaire
À propos de Julien
Co-fondateur - Scrum master & Expert technique
Utilisateur de Drupal depuis 2008, j’ai fait mes armes comme développeur chez Commerce Guys puis me suis mis à encadrer les nouveaux arrivants avant de donner des formations, participer aux avant ventes et accompagner les équipes au passage à Scrum.
Je suis impliqué dans la communauté française de Drupal depuis 2009, j’ai été tour à tour président puis vice-président de l’association Drupal France et francophonie entre 2011 et 2013.