Extra Block Types (EBT) - New Layout Builder experience❗

Extra Block Types (EBT) - styled, customizable block types: Slideshows, Tabs, Cards, Accordions and many others. Built-in settings for background, DOM Box, javascript plugins. Experience the future of layout building today.

Demo EBT modules Download EBT modules

❗Extra Paragraph Types (EPT) - New Paragraphs experience

Extra Paragraph Types (EPT) - analogical paragraph based set of modules.

Demo EPT modules Download EPT modules

Scroll
13/04/2025, by Ivan

Drupal 8 includes support for a configuration schema/metadata language based on Kwalify (http://www.kuwata-lab.com/kwalify/) for YAML configuration files. Kwalify itself is written in Ruby and required some modifications for our purposes, so not all Kwalify details apply directly, but it's quite close.

Cheatsheet

For a quick understanding and some helpful examples, refer to this cheat sheet, and continue reading if you still have questions:

ConfigSchemaCheatSheet1.5Thumb

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

Introductory Example

The System module has two configuration parameters related to maintenance mode (whether the site is in offline mode for visitors):

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

(Note: Whether maintenance is enabled is stored in the state system, not configuration.)

The default values for this configuration object are stored in core/modules/system/config/install/system.maintenance.yml as:

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

Each module can have as many configuration objects as needed. These are defined in one or more schema files provided with the module. In the System module, these files are found in core/modules/system/config/schema. The relevant section from system.schema.yml looks like:

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

The top-level key (system.maintenance) in the schema file corresponds to the base filename system.maintenance.yml and to the configuration object name config('system.maintenance'). The nested levels describe what is inside the file. Configuration schema predefines two file types: config_object for global configuration files and config_entity for entities. config_object is defined in core.data_types.schema.yml as:

# 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

The mapping type is a basic type for key-value pairs. Using config_object, the maintenance mode schema reuses keys langcode and _core and adds a message key. The label: 'Maintenance mode' describes the schema’s contents. The mapping section defines message while inheriting langcode and _core from the base type. Each item has a type and label key describing the data and its UI label.

In all core-supported cases, the top-level item in the .yml config file is a mapping described by the schema’s mapping list. You should use either config_object or config_entity subtypes. Items in the mapping can be of any type depending on the data. The _core key and all keys within it are reserved for Drupal core.

What Are Schema Files Used For?

1. To support multilingual features. We need tools to identify all translatable strings in shipped configuration so that we can offer translation suggestions via https://localize.drupal.org.

2. Schemas are used to create translation forms for config settings. The schema guides what fields are shown and how they behave in the translation UI.

3. Configuration schema is used by the persistence layer to correctly export configuration. You can skip writing schema if you implement toArray() in your config entity.

4. Schemas enforce value typecasting (e.g., strings vs integers) so deployment diffs reflect real changes and not accidental type changes.

5. PHPUnit's TestBase enforces default schema compliance. You can disable this with:

protected $strictConfigSchema = FALSE;

See https://drupal.org/project/config_inspector for a module that helps debug and inspect your schema.

There are more advanced use cases, such as generating web service interfaces based on schema metadata.

Properties

  • type: The value's type; can be a base or derived type (see examples below).
  • label: A UI label for the value. It does not have to match the form label exactly, but consistency improves clarity.
  • translatable: Indicates whether the value should be translatable. You can use:
type: label

as a shorthand for:

type: string
translatable: true
  • nullable: Whether the value can be null. Defaults to false if not specified.
  • class: Used for base types to assign a parsing class (examples below for TypedData and config types).
  • Type-specific properties:

mapping: Used for mapping types, listing the keys and value types.

sequence: Used for sequence types, listing the type of elements in a list.

Types Supported in Schema Files

As mentioned, basic types and some complex types are defined in core.data_types.schema.yml:

undefined:
  label: 'Undefined'
  class: '\Drupal\Core\Config\Schema\Undefined'

ignore:
  label: 'Ignore'
  class: '\Drupal\Core\Config\Schema\Ignore'

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'

Complex types:

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'

Mappings are associative arrays with explicitly defined keys. Sequences are indexed arrays where all items are of the same type.

Example Custom Complex Type

Defining a reusable "mail" type for email configuration:

mail:
  type: mapping
  label: 'Mail'
  mapping:
    subject:
      type: label
      label: 'Subject'
    body:
      type: text
      label: 'Body'

This "mail" type can be reused in schemas, such as:

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

Dynamic Type References

Types can be dynamic using placeholders:

  • [%key]: Uses the current key name
  • [%parent]: Uses a parent key
  • Combos like views.field.[table]-[field]

Example: image effects depend on the id field, so schema must dynamically reference that.

Naming Your Schema Files

Use globally unique names, preferably prefixed with your module name, to avoid conflicts.

Schema File Coding Style

  • Use single quotes for all strings
  • Do not quote keys or type names
  • Use consistent indentation (YAML requires it)
  • Provide meaningful labels for translatable strings

PHP API

To access typed configuration metadata:

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

Debugging Your Schema

Use the Config Inspector module to debug schema issues, check for missing types, and preview generated forms.

More Reference

Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.