logo

Types de blocs supplémentaires (EBT) – Nouvelle expérience de Layout Builder❗

Types de blocs supplémentaires (EBT) – types de blocs stylisés et personnalisables : diaporamas, onglets, cartes, accordéons et bien d’autres. Paramètres intégrés pour l’arrière-plan, la boîte DOM, les plugins JavaScript. Découvrez dès aujourd’hui le futur de la création de mises en page.

Démo des modules EBT Télécharger les modules EBT

❗Types de paragraphes supplémentaires (EPT) – Nouvelle expérience Paragraphes

Types de paragraphes supplémentaires (EPT) – ensemble de modules basé sur les paragraphes analogiques.

Démo des modules EPT Télécharger les modules EPT

Défilement
05/07/2025, by Ivan

Drupal 8 inclut le support d’un langage de schéma/métadonnées créé avec Kwalify (http://www.kuwata-lab.com/kwalify/) pour les fichiers de configuration YAML. Kwalify lui-même est écrit en Ruby, et quelques ajustements ont été nécessaires au format, donc toutes les spécificités de Kwalify ne s’appliquent pas directement, mais c’est assez proche.

Cheatsheet

Pour une compréhension rapide et quelques exemples pratiques, consultez cette fiche, puis continuez à lire si vous avez encore des questions :

ConfigSchemaCheatSheet1.5Thumb

/sites/default/files/config-schema-cheat-sheet1.5.pdf

Exemple d’introduction

Le module système a deux paramètres de configuration liés au mode maintenance (si le site est mis en maintenance pour les visiteurs normaux) :

<?php
$config = \Drupal::config('system.maintenance');
$message = $config->get('message');
$langcode = $config->get('langcode');
?>

(L’état de la maintenance est stocké dans le système state et non dans la configuration.)

Les valeurs par défaut de cet objet de configuration sont dans core/modules/system/config/install/system.maintenance.yml :

message: '@site is currently under maintenance. We should be back shortly. Thank you for your patience.'
langcode: en

Chaque module peut avoir autant d’objets de configuration que nécessaire. Tout cela est défini dans un ou plusieurs fichiers de schéma fournis avec le module. Pour le module système, ces fichiers sont dans core/modules/system/config/schema. La section de schéma correspondante dans system.schema.yml est :

system.maintenance:
  type: config_object
  label: 'Maintenance mode'
  mapping:
    message:
      type: text
      label: 'Message to display when in maintenance mode'

La clé de premier niveau ("system.maintenance") correspond au nom de base du fichier YAML ("system.maintenance.yml") et au nom de l’objet de configuration (config('system.maintenance')). Les niveaux imbriqués décrivent le contenu du fichier. Le schéma de configuration définit deux types de fichiers : config_object pour les fichiers globaux et config_entity pour les entités. Le type config_object est défini dans core.data_types.schema.yml :

# Root of a configuration object.

_core_config_info:
  type: mapping
  mapping:
    default_config_hash:
      type: string
      label: 'Default configuration hash'

config_object:
  type: mapping
  mapping:
    langcode:
      type: string
      label: 'Language code'
    _core:
      type: _core_config_info

Le mapping est le type de base pour les paires clé-valeur. En utilisant config_object, la définition du mode maintenance réutilise les clés langcode et _core et ajoute la clé message. La label décrit le contenu. Les éléments sont listés sous mapping avec un type et une étiquette pour décrire le type de données et fournir une description. L’étiquette est souvent semblable à celle utilisée dans les formulaires de configuration, où un administrateur peut modifier la valeur.

Dans tous les cas supportés par le cœur, l’élément de premier niveau dans le fichier YAML est un mapping dont les éléments sont décrits dans la liste mapping. Vous devez utiliser l’un des deux sous-types config_object ou config_entity. Les éléments individuels peuvent être de n’importe quel type selon votre définition. La clé _core et ses sous-clés sont réservées au cœur Drupal.

À quoi servent les fichiers de schéma ?

  1. Principalement pour le support multilingue : il faut un outil pour identifier toutes les chaînes traduisibles dans la configuration fournie, afin que lorsque vous envoyez vos propres paramètres, vues par défaut, rôles supplémentaires, éléments de menu, etc., ils puissent être proposés à la traduction via https://localize.drupal.org. Pour ce cas d’usage, les niveaux et types d’imbrication suffisent.
  2. Les schémas sont aussi utilisés pour fournir de vrais formulaires de traduction basés sur vos données. Le module de traduction de la configuration utilise les schémas pour générer les formulaires de traduction et sauvegarder les traductions. Les deux types traduisibles les plus importants sont « label » (pour les champs texte simples) et « text » (pour les champs texte multilignes).
  3. Grâce aux connaissances intégrées dans les schémas, la persistance par défaut des objets de configuration nécessite un schéma pour que les bonnes propriétés soient exportées avec les bons types. Vous pouvez ne pas fournir de schéma en implémentant la méthode toArray() dans votre entité de configuration, mais il est préférable de fournir des schémas.
  4. Le schéma est aussi utilisé pour associer automatiquement les valeurs aux types attendus, garantissant que les bonnes valeurs (pas uniquement des chaînes) sont sauvegardées. Ceci est important pour que les différences de configuration ne reflètent que des changements réels et non des variations de type.
  5. En PHPUnit, tous les tests dérivés de TestBase imposent strictement le respect du schéma de configuration par défaut. Les erreurs de schéma apparaîtront si un fichier de schéma manque ou est invalide. Vous pouvez désactiver cela dans votre test en définissant :
protected $strictConfigSchema = FALSE;

Consultez https://drupal.org/project/config_inspector, un module qui aide à déboguer vos schémas en identifiant les schémas manquants et en affichant différentes vues des données et des schémas.

D’autres usages sont possibles, comme la création d’interfaces web services basées sur ces schémas, et sûrement d’autres que la communauté découvrira.

Propriétés

  • type : type de la valeur, basique ou dérivé (voir exemples ci-dessous).
  • label : étiquette d’interface utilisateur pour la valeur. L’étiquette n’a pas besoin de correspondre exactement à celle du formulaire, mais la cohérence est recommandée.
  • translatable : indique si le type est traduisible. Par exemple :
type: label

est un raccourci pour :

type: string
translatable: true
  • nullable : si la valeur peut être vide ; par défaut elle ne l’est pas.
  • class : utilisé uniquement pour les types basiques afin d’assigner la classe qui réalise le parsing (exemples donnés pour TypedData et types de configuration définis dans le système).
  • Propriétés spécifiques aux types :

          - mapping : pour le type mapping, définit les éléments du mapping. Les clés doivent être des chaînes, et chaque valeur doit être décrite dans le schéma.
          - sequence : pour le type sequence, liste les éléments de la séquence. Les clés peuvent être entières ou chaînes, elles n’ont pas d’importance.

Types supportés dans les fichiers de métadonnées

Comme indiqué, les types de base et certains types complexes sont définis dans core.data_types.schema.yml :

# Type indéfini utilisé par le système quand
# aucun schéma n’est défini.
undefined:
  label: 'Undefined'
  class: '\Drupal\Core\Config\Schema\Undefined'

# Type explicite quand le typage n’est pas possible.
ignore:
  label: 'Ignore'
  class: '\Drupal\Core\Config\Schema\Ignore'

# Types scalaires basiques de TypedData.
boolean:
  label: 'Boolean'
  class: '\Drupal\Core\TypedData\Plugin\DataType\BooleanData'
email:
  label: 'Email'
  class: '\Drupal\Core\TypedData\Plugin\DataType\Email'
integer:
  label: 'Integer'
  class: '\Drupal\Core\TypedData\Plugin\DataType\IntegerData'
float:
  label: 'Float'
  class: '\Drupal\Core\TypedData\Plugin\DataType\FloatData'
string:
  label: 'String'
  class: '\Drupal\Core\TypedData\Plugin\DataType\StringData'
uri:
  label: 'Uri'
  class: '\Drupal\Core\TypedData\Plugin\DataType\Uri'

La plupart des types de données de base correspondent aux types du TypedData API. Ce modèle montre aussi comment définir vos propres types en assignant une classe. Les deux autres types complexes sont définis par des classes :

# Types conteneurs pour listes avec clés connues ou inconnues.
mapping:
  label: Mapping
  class: '\Drupal\Core\Config\Schema\Mapping'
  definition_class: '\Drupal\Core\TypedData\MapDataDefinition'
sequence:
  label: Sequence
  class: '\Drupal\Core\Config\Schema\Sequence'
  definition_class: '\Drupal\Core\TypedData\ListDataDefinition'

Mapping est une liste clé-valeur (tableau associatif) où chaque élément peut avoir un type différent. Sequence est une liste indexée simple (tableau numérique) où tous les éléments ont le même type ou un type dynamique identique. La différence essentielle est que dans sequence on ne connaît pas à l’avance les noms ou le nombre des clés, tandis que dans mapping les clés sont explicites. Les séquences peuvent aussi avoir des clés chaînes.

Les autres types définis (comme pour system.maintenance) héritent d’autres types, par exemple label, path, text, date_format et color_hex sont définis comme des chaînes, mais servent à aider les outils à mieux comprendre leur usage.

# Chaîne lisible par l’humain, texte simple éditable par un champ texte.
label:
  type: string
  label: 'Label'
  translatable: true

# Chemin interne Drupal
path:
  type: string
  label: 'Path'

# Chaîne lisible par l’humain, texte multilignes ou HTML.
text:
  type: string
  label: 'Text'
  translatable: true

# Format de date PHP, traduisible.
date_format:
  type: string
  label: 'Date format'
  translatable: true
  translation context: 'PHP date format'

# Valeur couleur HTML.
color_hex:
  type: string
  label: 'Color'

Les types label, text et date_format sont traduisibles, ce qui signifie que le module de traduction de l’interface identifie ces éléments et les traduit via les traductions fournies par la communauté ou l’administrateur, générant des fichiers de surcharges de traduction. Le contexte de traduction peut être spécifié (comme ici pour le format de date PHP), aidant les traducteurs à comprendre le sens exact.

Vous pouvez aussi définir des types complexes réutilisables, comme pour « mail » :

# Texte d’email avec sujet et corps.
mail:
  type: mapping
  label: 'Mail'
  mapping:
    subject:
      type: label
      label: 'Subject'
    body:
      type: text
      label: 'Body'

Cela crée un type « mail » réutilisable pour des réglages d’email, avec sujet et corps comme sous-éléments. C’est identique à la définition d’une clé de configuration, mais ce nom ne correspond pas à une clé existante, évitant tout conflit. Ce type peut être utilisé ailleurs (comme dans la configuration d’email du module utilisateur : user.schema.yml) :

user.mail:
 type: config_object
 label: 'Email settings'
 mapping:
  cancel_confirm:
    type: mail
    label: 'Account cancellation confirmation'
  password_reset:
    type: mail
    label: 'Password recovery'
  [....]

Enfin, les deux types complexes principaux pour définir des fichiers de configuration sont aussi dans core.data_types.schema.yml :

config_object:
  type: mapping
  mapping:
    langcode:
      type: string
      label: 'Language code'
    _core:
      type: _core_config_info

config_entity:
  type: mapping
  mapping:
    uuid:
      type: string
      label: 'UUID'
    langcode:
      type: string
      label: 'Language code'
    status:
      type: boolean
      label: 'Status'
    dependencies:
      type: config_dependencies
      label: 'Dependencies'
    third_party_settings:
      type: sequence
      label: 'Third party settings'
      sequence:
        type: '[%parent.%parent.%type].third_party.[%key]'
    _core:
      type: _core_config_info

Références dynamiques au type

Comme montré, même les types simples sont des références, et les types complexes comme « mail » sont souvent utilisés par référence. Parfois, le type de la valeur dépend des données, par exemple pour les styles d’image avec effets variés ou les vues avec différents plugins. On peut référencer des clés dans les données pour former des noms de types dynamiques.

Les valeurs variables dans les types doivent être encadrées par des crochets [], et peuvent être combinées avec des composants fixes. Il y a trois types de références :

  1. Référence à la clé d’un élément, ex. type: book.[%key]%key est remplacé par la clé de l’élément.
  2. Référence à une clé imbriquée, ex. type: 'views.field.[table]-[field]', où le type est calculé à partir des clés table et field dans une structure imbriquée.
  3. Référence à la clé du parent, ex. type: 'views.display.[%parent.display_plugin]', où la clé display_plugin du parent est utilisée pour déterminer le type.

Exemple dans les styles d’image (core/modules/image/config/install/image.style.medium.yml) :

name: medium
label: 'Medium (220x220)'
effects:
  bddf0d06-42f9-4c75-a700-a33cafa25ea0:
    id: image_scale
    data:
      width: 220
      height: 220
      upscale: true
    weight: 0
    uuid: bddf0d06-42f9-4c75-a700-a33cafa25ea0
langcode: en

La structure dépend du type d’effet indiqué dans id. Le type utilisé dépend donc des données et ne peut être statique. Les styles d’image configurés différemment auront différents effets. La spécification de type utilise donc une référence dynamique. La section du schéma correspondante dans image.schema.yml est :

image.style.*:
  type: config_entity
  label: 'Image style'
  mapping:
    name:
      type: string
    label:
      type: label
      label: 'Label'
    effects:
      type: sequence
      sequence:
        type: mapping
        mapping:
          id:
            type: string
          data:
            type: image.effect.[%parent.id]
          weight:
            type: integer
          uuid:
            type: string

Cela définit les métadonnées pour tous les styles d’image (image.style.*) comme mapping des noms, labels, et clés des effets. Les effets sont une séquence (nombre quelconque d’effets), chaque élément est un mapping détaillant l’effet. La clé de la séquence est l’UUID de l’effet, mais n’a pas d’importance (les séquences ne se préoccupent pas des clés). Les clés communes pour un effet sont id, data et weight, mais data dépend de id. Ainsi, image.effect.image_scale est un type référencé valide.

Notez que vous pouvez aussi trouver une définition différente de séquence où les éléments sont un unique tableau strict — ce format est déprécié et sera supprimé dans Drupal 9 :

deprecated.sequence.definition.format:
  type: sequence
  sequence:
    - type: string
      label: 'DO NOT COPY, THIS IS DEPRECATED' 

Noms de vos fichiers de schéma

Vos fichiers de schéma doivent avoir un nom globalement unique. Si un nom de fichier de schéma est identique à celui d’une autre extension, un des deux ne sera pas trouvé, causant des erreurs difficiles à déboguer. Il est donc recommandé de préfixer les fichiers de schéma avec le nom de votre module.

Style de code pour les fichiers de schéma

Suivez simplement le style YAML utilisé dans le cœur Drupal. Les points clés :

  • Ajoutez un commentaire en haut du fichier expliquant son contenu. Pour un seul fichier de schéma par module, un commentaire comme « # Schéma pour les fichiers de configuration du module Contact » suffit.
  • Évitez les commentaires redondants qui n’apportent pas de clarté supplémentaire.
  • N’utilisez pas de guillemets doubles pour les chaînes, préférez les guillemets simples.
  • Utilisez des guillemets simples pour les labels même pour un seul mot, pour la cohérence.
  • Ne mettez jamais de guillemets autour des définitions de clés ou types (car ils sont des chaînes sans espaces).
  • Dans Drupal, les entiers dans les fichiers YAML sont convertis en chaînes et doivent donc être entre guillemets simples.
  • Ajoutez des labels au minimum pour les valeurs à traduire (et les conteneurs qui les englobent). Voir l’outil Config Inspector pour vérifier que le schéma produit un formulaire correct.
  • Faites attention aux niveaux d’indentation, cruciaux en YAML pour la structure.

Note : Les fichiers YAML de configuration utilisent la convention d’ajouter des guillemets simples pour les chaînes multi-mots. Cette norme facilite les modifications ultérieures. Voir les standards de codage YAML Drupal. Les recommandations de style des schémas diffèrent car ils sont écrits manuellement, donc il est préférable d’être cohérent en entourant les labels de guillemets simples.

API PHP

Vous pouvez obtenir la configuration liée aux métadonnées via le service \Drupal::service('config.typed') (exemple pour le mode maintenance) :

$definition = \Drupal::service('config.typed')->getDefinition('system.maintenance');

La structure renvoyée est :

array(5) {
  ["label"]=>
  string(16) "Maintenance mode"
  ["class"]=>
  string(34) "\Drupal\Core\Config\Schema\Mapping"
  ["definition_class"]=>
  string(40) "\Drupal\Core\TypedData\MapDataDefinition"
  ["mapping"]=>
  array(2) {
    ["langcode"]=>
    array(2) {
      ["type"]=>
      string(6) "string"
      ["label"]=>
      string(13) "Language code"
    }
    ["message"]=>
    array(2) {
      ["type"]=>
      string(4) "text"
      ["label"]=>
      string(43) "Message to display when in maintenance mode"
    }
  }
  ["type"]=>
  string(18) "system.maintenance"
}

Exemple plus avancé pour obtenir les données typées du premier effet du style d’image « medium » :

// Récupérer la configuration typée pour la clé image.style.medium et ses effets.
// Prendre la clé uuid du premier effet dans la config (exemple plus haut).
$effects = \Drupal::service('config.typed')->get('image.style.medium')->get('effects.bddf0d06-42f9-4c75-a700-a33cafa25ea0.data')->getDataDefinition();

Cela retourne le type image.effect.image_scale décrit plus haut, avec une définition de map comme :

object(Drupal\Core\TypedData\MapDataDefinition)#1061 (3) {
  ["mainPropertyName":protected]=>
  NULL
  ["propertyDefinitions":protected]=>
  NULL
  ["definition":protected]=>
  array(5) {
    ["type"]=>
    string(24) "image.effect.image_scale"
    ["label"]=>
    string(11) "Image scale"
    ["class"]=>
    string(34) "\Drupal\Core\Config\Schema\Mapping"
    ["definition_class"]=>
    string(40) "\Drupal\Core\TypedData\MapDataDefinition"
    ["mapping"]=>
    array(3) {
      ["width"]=>
      array(2) {
        ["type"]=>
        string(7) "integer"
        ["label"]=>
        string(5) "Width"
      }
      ["height"]=>
      array(2) {
        ["type"]=>
        string(7) "integer"
        ["label"]=>
        string(6) "Height"
      }
      ["upscale"]=>
      array(2) {
        ["type"]=>
        string(7) "boolean"
        ["label"]=>
        string(7) "Upscale"
      }
    }
  }
}

L’API TypedData peut être entièrement utilisée pour manipuler ces éléments :

// Récupérer l’objet sequence des effets du style image medium.
$effects = \Drupal::service('config.typed')->get('image.style.medium')->get('effects');
// $effects est la séquence indexée par uuid comme dans l’exemple ci-dessus.
// Utiliser getValue() pour récupérer la valeur.
$first_uuid = key($effects->getValue());
// Prendre les données du premier effet.
$data = $effects->get($first_uuid)->get('data');
// Examiner valeurs et types pour width.
$data->get('width')->getPluginId(); // retourne 'integer'
$data->get('width')->getValue();    // retourne 220

Plus d’exemples de navigation dans la configuration basée sur le schéma et de génération de formulaires basés sur le schéma sont disponibles sur https://drupal.org/project/config_inspector.

Débogage de votre schéma

Le module Config Inspector offre une interface utilisateur pour comparer les schémas avec les données et voir comment les formulaires générés fonctionnent avec le schéma et les données. Il est utile pour trouver des problèmes dans le schéma. Voir aussi ce commentaire pour des conseils d’utilisation.

Le module de traduction de configuration du cœur fournit une interface utilisateur réelle sur les schémas pour permettre la traduction de la configuration. Vous pouvez utiliser ce module pour vérifier si votre configuration est bien traduite, et si les traductions apparaissent aux bons endroits (frontend) ou non (backend, où les utilisateurs éditent la configuration).

Ressources supplémentaires

Consultez les discussions sur les tickets Drupal concernant l’introduction et l’évolution du système de schéma, comme #1866610, #1648930, #1914366, #1905152, #1952394, #1602106, qui expliquent l’historique et les évolutions du système.