Module Development

What Are Configuration Entities? for Drupal 8, 9, 10, and 11

Configuration entities are suitable for creating user-defined configuration, such as image styles, views, content types, etc. A configuration entity type is defined by a module, default configuration is provided by that module as well as any other module, and then users can create zero or more configuration entities through Drupal's administrative UI.

In this tutorial, you will learn about:

  • What configuration entities are
  • Configuration entity types versus configuration entities
  • An example in core: image style
  • Overview of the process of creating your own configuration entity types in a module

Goal

Increase your understanding of configuration entities and the overall process of how they are created in a module.

Prerequisites

Watch: Introduction to Configuration Entities

Sprout Video

What are configuration entities?

Think of configuration entities as configuration you would empower a user to create and configure one or more times, in order to be used in some other configuration form. Consider the many places you can configure an image style—a configuration entity type—where you selected from a list of image styles that were already created.

For example, the core Image module defines the image style configuration entity type via a plugin and a schema YAML file, and it provides 3 default image styles (thumbnail, medium, and large) also in YAML files in its config/install directory. Any other module can also provide additional default image styles in their config/install or config/optional directories. Finally, an administrative user can create new image styles through the UI at /admin/config/media/image-styles/add.

Configuration entities can also have dynamic dependencies. They are dependent on the module that provides the configuration entity type, but they can also dynamically depend on other modules. For example, views.view.frontpage depends on the Views module but because it lists nodes it also depends on the Node module. If it's later updated to only show Article nodes, it will also gain a dependency on the Article configuration entity (node.type.article). (From Overview of Configuration (vs. other types of information) (Drupal.org)).

Configuration vs. content entities

Configuration entities enable us to store multiple sets of configuration. The Entity API in Drupal provides two types of entities:

Configuration entity

Used by the Configuration System. Supports translations, and can provide custom defaults for installations.

Content entity

Consists of configurable fields and base fields. Supports revisions and translations.

Entity types versus entities

Configuration entity types become necessary when configuration has a more complex structure and create, update, and delete operations need specific tailoring. Configuration entity types are implemented as plugins in Drupal and are defined in a PHP file by defining an annotation, extending the ConfigEntityBase class, and then, providing one or more YAML files that further define the configuration entities in the defining module's config/schema directory. Specific instances of these entity types, called configuration entities, are also defined in YAML files, using keys that follow the structure in the defining module's config/schema YAML files.

So while Views module defines the configuration entity type for views in core/modules/views/src/Entity/View.php and core/modules/views/config/schema, specific configuration entities of views, such as the frontpage view provided by the Node module in core/modules/node/config/optional/views.view.frontpage.yml is a configuration entity.

Example: configuration entity

There are many examples of configuration entities in core. But let's look at one example in the Image module.

The image style configuration entity type is defined with a plugin in the class Drupal\image\Entity\ImageStyle which is located in core/modules/image/src/Entity/ImageStyle.php. If you're curious about how entity types are defined see Entity API Implementation Basics.

Here is an excerpt of the plugin that defines the image style configuration entity.

/**
 * Defines an image style configuration entity.
 *
 * @ConfigEntityType(
 *   id = "image_style",
 *   label = @Translation("Image style"),
 *   handlers = {
 *     "form" = {
 *       "add" = "Drupal\image\Form\ImageStyleAddForm",
 *       "edit" = "Drupal\image\Form\ImageStyleEditForm",
 *       "delete" = "Drupal\image\Form\ImageStyleDeleteForm",
 *       "flush" = "Drupal\image\Form\ImageStyleFlushForm"
 *     },
 *     "list_builder" = "Drupal\image\ImageStyleListBuilder",
 *     "storage" = "Drupal\image\ImageStyleStorage",
 *   },
 *   admin_permission = "administer image styles",
 *   config_prefix = "style",
 *   entity_keys = {
 *     "id" = "name",
 *     "label" = "label"
 *   },
 *   links = {
 *     "flush-form" = "/admin/config/media/image-styles/manage/{image_style}/flush",
 *     "edit-form" = "/admin/config/media/image-styles/manage/{image_style}",
 *     "delete-form" = "/admin/config/media/image-styles/manage/{image_style}/delete",
 *     "collection" = "/admin/config/media/image-styles",
 *   },
 *   config_export = {
 *     "name",
 *     "label",
 *     "effects",
 *   }
 * )
 */

class ImageStyle extends ConfigEntityBase implements ImageStyleInterface, EntityWithPluginCollectionInterface {

  /**
   * The name of the image style.
   *
   * @var string
   */
  protected $name;

  /**
   * The image style label.
   *
   * @var string
   */
  protected $label;

  /**
   * The array of image effects for this image style.
   *
   * @var array
   */
  protected $effects = array();

  /**
   * Holds the collection of image effects that are used by this image style.
   *
   * @var \Drupal\image\ImageEffectPluginCollection
   */
  protected $effectsCollection;

  /**
   * {@inheritdoc}
   */
  public function id() {
    return $this->name;
  }

...

View the full source for class ImageStyle (api.drupal.org).

Schema

The schema or structure for the image style configuration entity is defined in core/modules/image/config/schema/image.schema.yml.

Note the type: config_entity at the top, indicating that it is a configuration entity type definition.

Here is the schema for the image style configuration entity (core/modules/image/config/schema/image.schema.yml).

# Schema for configuration files of the Image module.

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

image.effect.*:
  type: mapping
  label: 'Effect settings'

image.effect.image_crop:
  type: image_size
  label: 'Image crop'
  mapping:
    anchor:
      label: 'Anchor'
      type: string

image.effect.image_convert:
  type: mapping
  label: 'Convert'
  mapping:
    extension:
      label: 'Extension'
      type: string

image.effect.image_resize:
  type: image_size
  label: 'Image resize'

image.effect.image_rotate:
  type: mapping
  label: 'Image rotate'
  mapping:
    degrees:
      type: integer
      label: 'Rotation angle'
    bgcolor:
      label: 'Background color'
      type: color_hex
    random:
      type: boolean
      label: 'Randomize'

image.effect.image_scale:
  type: image_size
  label: 'Image scale'
  mapping:
    upscale:
      type: boolean
      label: 'Upscale'

# The image desaturate effect has no settings.
image.effect.image_desaturate:
  type: sequence

image.effect.image_scale_and_crop:
  type: image_size
  label: 'Image scale and crop'

image.settings:
  type: config_object
  mapping:
    preview_image:
      type: string
      label: 'Preview image'
    allow_insecure_derivatives:
      type: boolean
      label: 'Allow insecure image derivatives'
    suppress_itok_output:
      type: boolean
      label: 'Suppress the itok query string for image derivatives'

field.storage_settings.image:
  type: field.storage_settings.file
  label: 'Image settings'
  mapping:
    default_image:
      type: field_default_image
      label: 'Default value'

field.field_settings.image:
  type: base_file_field_field_settings
  label: 'Image settings'
  mapping:
    max_resolution:
      type: string
      label: 'Maximum image resolution'
    min_resolution:
      type: string
      label: 'Minimum image resolution'
    alt_field:
      type: boolean
      label: 'Enable Alt field'
    alt_field_required:
      type: boolean
      label: 'Alt field required'
    title_field:
      type: boolean
      label: 'Enable Title field'
    title_field_required:
      type: boolean
      label: 'Title field required'
    default_image:
      type: field_default_image
      label: 'Default value'

field.value.image:
  type: field_default_image
  label: 'Default value'

field.formatter.settings.image:
  type: mapping
  label: 'Image field display format settings'
  mapping:
    image_link:
      type: string
      label: 'Link image to'
    image_style:
      type: string
      label: 'Image style'

field.widget.settings.image_image:
  type: mapping
  label: 'Image field display format settings'
  mapping:
    progress_indicator:
      type: string
      label: 'Progress indicator'
    preview_image_style:
      type: string
      label: 'Preview image style'

Default configuration

It's good practice to provide default configuration for a configuration entity. Here is an example of default configuration for a large image style in core/modules/image/config/install/image.style.large.yml.

In this same directory, you'll find other image style configuration entities that are installed on the site when the image module is enabled (thumbnail and medium).

To learn more about default configuration, the difference between config/install and config/optional directories, and how Drupal only reads these directories once when the module is installed, resulting in sites owning configuration (not modules), see Default Configuration in a Module.

langcode: en
status: true
dependencies: {  }
name: large
label: 'Large (480×480)'
effects:
  ddd73aa7-4bd6-4c85-b600-bdf2b1628d1d:
    uuid: ddd73aa7-4bd6-4c85-b600-bdf2b1628d1d
    id: image_scale
    weight: 0
    data:
      width: 480
      height: 480
      upscale: false

If you have a Drupal site installed, from the Administrative menu, go to Configuration > Image styles (admin/config/media/image-styles) to see several examples of image style configuration entities.

Image
Screenshot shows the administrative page for image styles

Recap

In this tutorial, you learned more about configuration entities and how they are created in a module.

Further your understanding

  • What criteria could you use to decide if you need to implement a configuration or a content entity? (See also Entity API Overview.)

Additional resources

Decoupled Headless Drupal