Config Actions List¶
The following config actions are available in Drupal core.
Also see the Contrib Config Actions List.
All Config Actions by type.¶
- Applicable to all config entity types
- cloneAs
- create
- createIfNotExists
- createForEach / createForEachIfNotExists
- disable
- enable
- setStatus
- set / setMultiple
- setThirdPartySetting(s)
- simpleConfigUpdate
- Applicable to specific config entity types
- add(EntityType) - Workflows
- addNavigationBlock
- allowLayoutOverrides
- addItemToToolbar - CKEditor
- setFilterConfig - CKEditor
- addToAllBundles - field storage
- createCopy
- enableLayoutBuilder
- disableLayoutBuilder
- grantPermission(s)
- hideComponent(s)
- placeBlockInAdminTheme/placeBlockInDefaultTheme
- setComponent(s)
- setDefaultValue
- setDescription
- setLabel
- setMessage
- setRecipients
- setRedirectPath
- setRegion
- setReply
- setRequired
- setSettings
- setTranslatable
- setWeight
- Config Entity Wildcards
- Adding the same permission(s) to all user roles
- Affecting every view display of every content type
- Changing settings on every instance of a field
- Creating a view display (i.e., enabling a view mode) for every content type
- Overriding a base field for every media type
Config Actions sorted by entity type.¶
block.block.*
- placeBlockInAdminTheme/placeBlockInDefaultTheme
- setRegion
- setWeight
core.entity_form_display.*.*.*
core.entity_view_display.*.*.*
- hideComponent(s)
- setComponent(s)
- allowLayoutOverrides
- enableLayoutBuilder
- disableLayoutBuilder
contact.form.*
- setMessage
- setRecipients
- setRedirectPath
- setReply
- setWeight
editor.editor.*
- addItemToToolbar
field.field.*.*.*
- setDefaultValue
- setDescription
- setLabel
- setRequired
- setSettings
- setTranslatable
field.storage.*.*
- addToAllBundles - field storage
filter.format.*
- setFilterConfig
navigation.block_layout
- addNavigationBlock
user.role.*
- grantPermission(s)
workflows.workflow.*
- add(EntityType)
Applicable to all config entity types¶
cloneAs¶
Use the cloneAs
config action to create a clone of any config entity with a
new ID.
This will create a image.style.thumbnail_widescreen
config entity.
If the cloned entity already exists (identified by its ID), it will be left untouched.
If you want to use a wildcard to clone, use the createCopy
config action.
create¶
The create
config action can be used to create a config entity. This action
will error out if the entity (identified by ID) already exists.
It is not likely to be often useful in recipes on its own as it is preferred to
use the /config
folder to create config entities.
createIfNotExists¶
The createIfNotExists
config action extends the create
config action and can
be used to conditionally create a config entity if it does not exist. Existence
is determined by it having the same ID.
If your recipe needs a particular config entity to exist (by ID), but does not
care about what it contains, use createIfNotExists
. This way is best for
things like user roles, where you most likely don't care about its label or
weight, but probably just want to add some permissions (which you can do with a
config action).
If the recipe needs to create a config entity and requires that it look a particular way, putting it in the config directory is the way forward. This way is best for things like fields, which generally must have specific configurations that affect the way data is stored.
In Drupal 10.4+, you can also use config:strict
to allow for leniency when
comparing config in your recipe to the config in Drupal.
createForEach / createForEachIfNotExists¶
The createForEach
and createForEachIfNotExists
config actions are used to
loop over bundle config entities to create other config entities that are
coupled to those bundles.
These actions are meant to be used with wildcards, and can only work on entities that are bundles of another entity type, such as node types, media types, taxonomy terms, and so forth.
A classic use case is making every content type translatable. This requires creating a language.content_settings.node.TYPE entity for each node type.
config:
actions:
node.type.*:
createForEach:
language.content_settings.node.%bundle:
target_entity_type_id: node
target_bundle: %bundle
In this config action, the %bundle
placeholder will be replaced with the ID of
the node type being processed. For example, when processing a blog node type, it
will create a corresponding language.content_settings.node.blog
entity.
Let's say you want to create content settings and an image style for each
content type. You can use createForEach
to create multiple entities at once:
config:
actions:
node.type.*:
createForEachIfNotExists:
language.content_settings.node.%bundle:
target_entity_type_id: node
target_bundle: %bundle
image.style.node_%bundle_thumbnail:
label: 'Thumbnail for %label content'
For a blog content type, this will create both a
language.content_settings.node.blog
entity and an
image.style.node_blog_thumbnail
. In the array values (but not the keys) you
can use the %label
placeholder to insert the human-readable label of the
bundle being processed.
disable¶
Marks any config entity as "disabled". The effect of this varies by config entity type. For example, disabling a view keeps it editable in the administrative UI, but makes it unavailable everywhere else. Works on all config entities.
enable¶
Marks any config entity as "enabled". The effect of this varies by the config entity type. Works on all config entities.
setStatus¶
Sets the status of the configuration entity. Works on all config entities.
# Enable views.view.latest
config:
actions:
views.view.latest:
setStatus: true
# Disable views.view.latest
config:
actions:
views.view.latest:
setStatus: false
set / setMultiple¶
Changes a property of a config entity. This is a pretty low-level method and should generally only be used if no dedicated method exists. Works on all config entities.
setMultiple
is the same as set
, but accepts multiple property/value pairs.
user.role.authenticated:
setMultiple:
- property_name: label
value: Logged-in user
- property_name: is_admin
value: false
setThirdPartySetting(s)
¶
The setThirdPartySetting(s)
config actions allows the recipe author to set
third-party settings values for any config entity that can carry third-party
settings, which at the time of this writing includes all config entities.
Helpful for modules like Layout Builder and Scheduler that use these settings
to provide or change functionality.
Singular:
config:
actions:
core.entity_view_display.node.test.full:
setThirdPartySetting:
module: layout_builder
key: enabled
value: true
To set multiple third-party settings:
config:
actions:
core.entity_view_display.node.test.full:
setThirdPartySettings:
-
module: layout_builder
key: enabled
value: true
-
module: layout_builder
key: allow_custom
value: true
simpleConfigUpdate¶
A globally applicable config action, simpleConfigUpdate
, can be used to
make updates to any configuration value. Despite its name, this action can be
applied to any type of configuration. (There's a @todo
in the code
questioning whether this is correct.)
Sample usage to update the page.front
value in the system.site
simple
configuration:
The plural version takes the same name as the singular but passes multiple arguments. Example:
Applicable to specific config entity types¶
These config actions can be applied to specific config entity types.
add(EntityType) - Workflows¶
If you have an entity type or entity bundle that you want to add to a content moderation workflow, you can use config actions.
config:
actions:
workflows.workflow.editorial:
# Opt only certain content types into moderation.
addNodeTypes: [page, article]
# Opt every taxonomy vocabulary into moderation.
addTaxonomyVocabularies: '*'
The action is dynamic and automatically converts singular entity type plugin
IDs, like taxonomy_vocabulary
, into plural strings like TaxonomyVocabularies
so it will work with custom and additional config entity types. Just "pluralize"
the plugin ID, remove any underscores, convert to SentenceCase, and prepend
add
. For example, the paragraph_type
entity type will become
addParagraphTypes
.
addItemToToolbar - CKEditor¶
To add a new toolbar item, optionally at a specific position, and optionally
replacing the item that's already in that position, use the addItemToToolbar
config action.
config:
actions:
editor.editor.foo:
addItemToToolbar:
item_name: MediaLibrary
# Specific zero-based position in the toolbar.
# If not specified, it appends to the end.
position: 3
# If there's already something at that position, replace it.
# For example, replace the Image button with Media library. By default,
# existing items are left where they are, and the new item is inserted
# right before them.
replace: true
addNavigationBlock - navigation¶
You can add new blocks to Navigation using the addNavigationBlock
config
.action
config:
actions:
navigation.block_layout:
addNavigationBlock:
# The position in the navigation the block is going to be added.
delta: 1
# The configuration array for the navigation item.
configuration:
id: 'navigation_menu:content'
label: Content From Recipe
label_display: 1
provider: navigation
level: 1
depth: 2
This action can be only used against the navigation.block_layout
config.
allowLayoutOverrides¶
This action allows you to configure Layout builder overrides on entity view displays config files.
See also:enableLayoutBuilder
disableLayoutBuilder
addToAllBundles - field storage¶
If you have a field that you want to add to every content type, but you don't
know how many content types there are, or what they're called, there's an
addToAllBundles
config action that will automatically add a field to every
content type.
For example, if you have a field storage called
field.storage.node.field_meta_tags
, and you want to add it to every content
type:
config:
actions:
field.storage.node.field_meta_tags:
addToAllBundles:
label: Meta tags
description: Choose your meta tags for this content.
This action works exactly the same way for fields that attach to media types, taxonomy terms, or any other fieldable entity type. You can specify the field's label and user-facing description, and it will be the same for every bundle. At the time of this writing, you cannot change the settings of the new fields; they will be created with their default settings.
By default, the addToAllBundles
action will not conflict with fields that
already exist. So, for example, if you have field_meta_tags
tags on your
article
content type, but not your page
and blog_post
content types, the
action will add the field to the page
and blog_post
content types, but the
one on article
will be left alone. However, if you specify the
fail_if_exists
flag, an error will occur if the field already exists on any
content type:
config:
actions:
field.storage.node.field_meta_tags:
addToAllBundles:
label: Meta tags
description: Choose your meta tags for this content.
# If field_meta_tags already exists on any content type, you'll get an error.
fail_if_exists: true
Another thing to bear in mind is that this action will add the field to every
bundle, but it will NOT make the field visible to editors or users. To do that,
you will also need to use the setComponent
action of entity view displays and
entity form displays. Here, then, is a complete example of adding a field to
every content type, and then ensuring it's available to editors and viewers:
config:
actions:
field.storage.node.field_byline:
addToAllBundles:
label: Byline
description: The name of the person who wrote this content.
# Make sure the field is visible on the node edit forms.
entity_form_display.node.*.default:
setComponent:
field_byline:
type: text_textfield
# Ensure the field is visible when viewing content.
entity_view_display.node.*.full:
setComponent:
field_byline:
type: text_default
createCopy¶
If you want to use a wildcard to clone the entity view or form display for a
particular mode of every bundle, you could use the new createCopy
action,
which only applies to entity view and form displays.
If you have two content types, page and blog, this will create two entities that are clones of the teaser displays for those content types.
core.entity_view_display.node.page.search_result
core.entity_view_display.node.blog.search_result
disableLayoutBuilder¶
This action allows you to disable Layout builder on entity view displays.
See also:allowLayoutOverrides
enableLayoutBuilder
enableLayoutBuilder¶
This action allows you to enable Layout builder on entity view displays.
See also:allowLayoutOverrides
disableLayoutBuilder
grantPermission(s)¶
Used to add permissions to user roles.
Singular:
Multiple:
config:
actions:
user.role.editor:
grantPermissions:
- 'delete any article content'
- 'edit any article content'
User roles also have specialized actions that allow you to grant permissions
that are specific to a particular bundle -- for example, permissions that are
defined per content type, or per media type, such as create page content
or
edit own image media
. If you want to grant one of these permissions for
every bundle of an entity type, you can use config actions to do it
dynamically.
For example, to grant the ability for a role to edit their own content, for every content type:
The token %bundle
is dynamically replaced by the machine name of the bundle.
It also works for media types:
config:
actions:
user.role.media_creator:
grantPermissionsForEachMediaType:
- 'create %bundle media'
- 'delete own %bundle media'
And taxonomy vocabularies:
config:
actions:
user.role.info_architect:
grantPermissionsForEachTaxonomyVocabulary:
- 'create %bundle terms'
Advanced: Any entity type that supports bundles will automatically have
actions like this. The name of the action is derived from the machine name (ID)
of the bundle entity type. So say that paragraph
entities' bundles are defined
by paragraph_type
entities; this will result in a config action called
grantPermissionsForEachParagraphType
, which allows you to grant paragraph
type-specific permissions to a user role.
hideComponent(s)¶
Hides a component from an entity view display or entity form display.
hideComponents
is the same as hideComponent
, but hides more than one
component.
placeBlockInAdminTheme/placeBlockInDefaultTheme¶
To allow for flexibility when placing blocks, recipe authors can leverage the
placeBlockInDefaultTheme
and placeBlockInAdminTheme
config actions. These
allow for a block to be placed in the site's currently configured default theme
(shown to anonymous users) or admin theme (shown on admin pages to users with
permission), respectively.
config:
actions:
block.block.powered_first_default:
placeBlockInDefaultTheme:
id: powered_first
# The region accepts an array keyed by theme name.
region:
bootstrap: footer
gesso: page_bottom
olivero: footer_top
# A fallback used if no match found in the region array.
default_region: content
# Place the block before any blocks already in the region.
position: first
plugin: system_powered_by_block
block.block.powered_last_admin:
placeBlockInAdminTheme:
id: powered_last
# The region accepts an array keyed by theme name.
region:
gin: pre_content
claro: content
# Place the block after any blocks already in the region.
position: last
plugin: system_powered_by_block
Note that the region accepts a mapped array to set the preferred region per theme. A default_region can also be provided to act as a fallback, in case the preferred region can't be found in the theme.
Also, the position value can be used to place a block as either the first or last block in the intended region. If provided, a weight value will be calculated to ensure that the block appears at the intended position.
setComponent(s)¶
To add a field to an entity's view or form displays, you can use
setComponent(s)
.
Singular:
config:
actions:
core.entity_view_display.node.article.default:
setComponent:
name: field_tags
options:
type: entity_reference_label
label: above
settings:
link: true
third_party_settings: { }
weight: 10
region: content
A pluralized version, adding the configuration for multiple fields:
config:
actions:
core.entity_view_display.node.article.default:
setComponents:
-
name: field_tags
options:
type: entity_reference_label
label: above
settings:
link: true
third_party_settings: { }
weight: 10
region: content
-
name: field_categories
options:
type: entity_reference_label
label: above
settings:
link: true
third_party_settings: { }
weight: 11
region: content
setDefaultValue¶
Sets the default value of a field, which can be changed by users when editing content. Exactly what the default value should look like, varies by field type. Works on fields and base field overrides.
setDescription¶
Changes the user-facing description of a field. Works on fields and base field overrides.
field.field.node.page.field_byline:
setDescription: 'Enter the name or credit of whoever created this magnificent page.'
setFilterConfig¶
This action allows you to set a filter for an existing Ckeditor text format.
config:
import:
actions:
filter.format.full_html:
setFilterConfig:
instance_id: filter_id
configuration:
id: filter_id
provider: module_name
status: true
weight: 0
settings: { }
setLabel¶
Changes the human-readable label of a field. Works on fields and base field overrides.
setMessage¶
Sets the message that a contact form should display to users when they submit the form. Only works on contact forms.
setRecipients¶
Sets the email addresses that should be notified when a user submits a contact form. Accepts an array of email addresses. Only works on contact forms.
setRedirectPath¶
Sets the path (URL) where users should be redirected when they submit a contact form. Must start with a slash. Only works on contact forms.
setRegion¶
Sets the region in which a block should be. Which regions are available depends on which theme the block is in. Only works on blocks.
setReply¶
Sets a message to be emailed to the person who submitted a contact form. Only works on contact forms.
contact.form.feedback:
setReply: 'We have received your feedback and will get back to you at some point when the planets align properly.'
setRequired¶
Sets whether users must enter a value for a field. Works on fields and base field overrides.
setSettings¶
Changes field settings. Exactly which settings are available, and what they mean, varies by the field type. Any preexisting settings are added automatically, with the incoming settings taking precedence. Works on fields and base field overrides.
setTranslatable¶
Sets whether a field should be translatable in the UI, or not. Works on fields and base field overrides. (Note that most fields are translatable by default.)
setWeight¶
Blocks:
Sets the weight (position relative to other blocks in the same region of the same theme) of a block. Accepts any number. Works on Blocks.
Contact forms:
Sets the weight of the contact form, relative to other contactforms, in the administrative UI. Accepts a number. Only works on contact forms.
Config Entity Wildcards¶
You can use wildcards in your recipe to apply actions to multiple config entities of the same type.
Here are some examples of possible uses:
Adding the same permission(s) to all user roles¶
Affecting every view display of every content type¶
actions:
core.entity_view_display.node.*.*:
setComponent:
name: field_tags
options:
type: entity_reference_label
label: above
settings:
link: true
third_party_settings: { }
weight: 10
region: content
Changing settings on every instance of a field¶
Creating a view display (i.e., enabling a view mode) for every content type¶
actions:
core.entity_view_display.node.*.foo:
createIfNotExists:
# The contents of the view display here...
Overriding a base field for every media type¶
actions:
core.base_field_override.media.*.thumbnail:
createIfNotExists:
# The contents of the base field override here...
Note that you cannot use wildcards on simple config (such as gin.settings
),
or all config provided by a specific module. For example, something like
node.*
to target all config provided by the Node module, won't work.
You also cannot use wildcards on config prefixes. For example, these are all invalid and will raise exceptions:
# Won't hit field.field and field.storage.
field.*.media.foo.field_bar
# Won't hit all configs provided by a project.
node.*.something
# Won't hit config from any module that provides something called a "vocabulary".
*.vocabulary.wat
In other words, you can only put wildcards in the "identifying" parts of a config entity's full name.
This is due to the way config entities relate to the underlying config schema.
Using input tokens as wildcards¶
As of Drupal 11.1.2 (not in Drupal 10), you can use the input tokens to dynamically target config entities, with certain limitations.
config:
actions:
node.type.${content_type}:
setDescription: 'Changing the description of a user-chosen node type!'
You can only use the tokens in the identifying parts of the config entity ID,
for example, a node type's actual machine name, node.type.${content_type}
.
Input tokens can also only be used on configuration entity names. The can't be used in simple config names.