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
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.
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
- Annotations (Drupalize.Me)
- Entity API Overview (Drupalize.Me)
- Entity API Implementation Basics (Drupalize.Me)
- Configuration schema/metadata (Drupal.org)
- Change record: Configuration entities are now supported by the typed data system (Drupal.org)