Config Actions¶
Config Actions provides a pluggable framework for easily manipulating configuration data via simple YAML files with the goal of creating truly reusable software components in Drupal.
Example use cases include:
- Templates
the ability to provide a configuration template file containing variables that can be reused and replaced to create new configuration. For example, a template for adding a certain field to a content type where the content type isn’t yet known.
- Override
the ability to easily “override” configuration provided by core or other modules. These is not a “live” overrides system but simply a method to import changes into the config system.
NOTE: This is a Developers module and requires creating custom modules containing YAML files that contain the config actions to be performed.
Getting Started¶
Config Actions provides a pluggable framework for easily manipulating configuration data via simple YAML files with the goal of creating truly reusable software components in Drupal.
Example use cases include:
- Templates
the ability to provide a configuration template file containing variables that can be reused and replaced to create new configuration. For example, a template for adding a certain field to a content type where the content type isn’t yet known.
- Override
the ability to easily “override” configuration provided by core or other modules. These is not a “live” overrides system but simply a method to import changes into the config system.
NOTE: This is a Developers module and requires creating custom modules containing YAML files that contain the config actions to be performed.
Action Files¶
Actions are listed in a config_actions.yml
file located in the top-level folder
of your custom module. When your module is enabled, the actions in this file
will be executed.
@TODO: A drush interface allows you to execute actions manually.
@TODO: When Drupal Updates are run, any new actions added to your file are executed automatically.
An action is a list of “option” keys and values. Various global options are available, and additional options can be added by specific plugins.
Nested Actions¶
Actions can be nested within each other. Using the actions
option you can
list additional sub-actions to be executed. All options from the main parent
action are inherited in each sub-action but can be overridden by the sub-action.
For example, the top-level action can specify the source
and dest
options
then each sub-action could specify different plugins, or different replace
option values, or even override with different source
or dest
values.
This allows related actions to be grouped and reduces the amount of repeated
text between similar actions.
When nesting or naming actions, each new action within the actions
list
requires a unique id key.
For example:
actions:
myaction1:
option1: value1
option2: value2
myaction2:
option1: value1
option2: value2
...
Global Options¶
Actions consist of a simple array of key/value options. The following global keys are recognized:
- plugin
- Specifies the name of the Config Actions Plugin to be used to execute the action. If omitted, the “Default” plugin is used.
- source
- The source data specifier. Can be a config id, a
*.yml
file, or a raw data array. Contains the source config data to be manipulated. - dest
- The destination specifier. Can be a config id or a
*.yml
file. The modified data will be stored to this location. If omitted, the source is used as the destination. - replace
- An optional key/value array that contains string replacement patterns and values. Can be used to replace patterns in the source data or in any other option value.
- replace_in
- An optional array listing the options that the
replace
is performed in. The default value of this depends on the specific plugin being used. The array given here replaces the default list for the current action.
Plugins¶
Additional plugins can be written to extend Config Actions.
Some plugins implement the ValidatePaths trait which adds additional options for specifying a path into the source data and validating that path. These options are described later.
The plugins currently available as part of the base module are:
- default
- The default plugin used when no other is specified. This plugin
simply reads the config from the
source
, performs string replacement in the keys and values of the data, and saves the result to thedest
. - change
- Uses ValidatePaths. Changes the data at the source to the
specified
value
option. - add
- Uses ValidatePaths. Adds a new
value
at the specified location in the source. Typically used to add additional array items. - delete
- Uses ValidatePaths. Clears the data at the specified location in the source, or completely deletes a specific configuration item.
- include
- Loads and runs a specific
action
from a differentmodule
. Allows thereplace
values to override those specified in the other module. Used to create reusable actions in your module that can be used by other modules.
Path Validation¶
Some plugins specify a path within the source data. A path is simply an array of keys to be traversed within the source tree. The following options are added by this trait:
- path
- The array of keys used to specify the path in the source data
- current_value
- The optional current value in the source path. Used to ensure that the specified value exists in the source before manipulating it. This must be specified to enable path validation.
- value_path
- An optional path to be used instead of the normal
path
for validating thecurrent_value
. Used when changing the value inpath
but testingcurrent_value
in a differentvalue_path
.
Source Plugins¶
The source
and dest
use a second plugin system used to load and save
configuration data. The provided plugins are:
- id
- The specifier is a string value that points to a specific config item id within the active config storage.
- file
- The specifier is a
*.yml
file along with optional path. If no path is given, the config/templates directory of the current module is used.
Normally the source plugin type is determined from the string specifier itself.
For example, if the string ends in .yml
then the file
plugin is used.
To override the source plugin type, use the *_type
option (source_type
or
dest_type
) with the name of the plugin.
The source can also be a raw array of configuration data. This data is passed
to the plugin system in case a complex plugin needs to parse the additional
data. But since the id
and file
plugins both expect a string value, any
array value is currently passed through as raw data.
The following action data (placed in config_actions.yml
) will load templates
within the config/templates folder (see the tests/modules/test_config_actions
test module for these template files):
# this contains any global variables that are available to any template
replace:
"%field_name%": "myproject_image"
# Here are some sample actions
actions:
# *****
# Example of "template" plugin
# *****
# Replace any tokens in a template to create a new config item
field_storage:
# name of yml file in config/templates folder
source: "field.storage.node.image.yml"
dest: "field.storage.node.%field_name%"
field_instance:
source: "field.field.node.image.yml"
dest: "field.field.node.%bundle%.%field_name%"
actions:
article:
replace:
"%bundle%": article
page:
replace:
"%bundle%": page
The top-level action has a replace
option for the global %field_name%
variable. The % characters are used in the template to specify a replaceable
variable, but any delimiter could be used as needed. Avoid using [] or {} to
specify variables since those could be interpreted as YAML arrays.
Next, the top-level action uses the actions
option to specify a list of
sub-actions. These sub-actions will inherit the global %field_name%
replacement.
The field_storage
sub-action (where field_storage
is just a unique value
within this array used to give a name to the sub-action) loads a source
template *.yml
file and outputs the config to a config id that will create a
new field_storage entity in Drupal. %field_name%
will be replaced with
myproject_image
.
The field_instance
sub-action sets a source *.yml
file and a destination
and then has it’s own sub-action list for each bundle that needs to have a
field instance created. Each sub-action (article
and page
) has it’s own
value of the %bundle%
variable that is used in the template replacement.
If this action file is executed, a field called myproject_image
will be
created and added to the page
and article
content types.
But you can also call this action from your own module and override the
%field_name%
variable to create other fields. You could create different
template actions for different types of fields.
For example, you could create a “Location Feature” that has a template for how to add geofield data to a content type. Rather than saving the specific configuration for the content type, field storage, and field instances in a feature that would still contain your hardcoded field names and content type names, you can use Config Actions to create template “features” that can be reused across your projects with different field names and content types.