Configuration System in Drupal 8 is a new suite of tools that allow us to take config and make it exportable. In this post, I am going to outline three items you need to know to begin working with the configuration system.
Config vs Content
It is important to note that not all data in Drupal are created equally. There is a concept of configuration and content. I like this distinction made in Drupal’s config API docs:
Configuration vs. Content: Configuration tends to define "types of things", such as content types, taxonomy vocabularies, etc. Then each "thing" within the type is a piece of content: a content node, a taxonomy term, etc.
Armed with that knowledge, what of the following is config and what is content?
- New Content Type “News Update”
- New Field storage for “News Update” content type
- New View mode for Content Type “News Update”
- A new node with title “Alert this is not content ;)” from content type “News Update
All but the last one is considered config. This is a relatively straight-forward example but it is incredibly important to understand while working with config export, you will not be exporting your whole site but only the config values. This should handle most use cases but there are some edge cases around deploying blocks, menus and even content through your testing environments and up to production. See further learning section below for more resources.
Active vs Staging configuration and overrides
Out of the box, configuration management is enabled and all config is stored in your database. The database is where active configuration is stored and what Drupal will use for your site. While config export and import is available via the UI, developers will typically interact with config via drush. Part of the configuration workflow is that you make changes locally, export the config and save them.
These config files make up your staging config and should be saved in the directory set to $config_directories['sync’] in your settings.php. This directory is where the configuration import will pull in changes and apply it to your site. Lastly, we have the opportunity to override configuration values by setting the $config value in the settings.php file. This is good to use when you don’t want a token or sensitive data to live in your exported config that may be tracked in your version control system (VCS). It is also worth mentioning that when a value has an override, it doesn’t display so in the UI. If you find yourself not able to update the value in the UI, it is possible it has an override.
Another way to determine if there are any overrides is by comparing the output of the following commands:
drush config-get system.site --include-overridden
drush config-get system.site
The first command will get the overridden values in the settings.php file. If you know the config value you are looking for you can always pipe that with a grep:
drush config-get system.site --include-overridden | grep config_name
Configuration management is only to share configuration between to identical databases. The way this works is each config file has a UUID that represents the database it is from. While importing, if the system finds that the UUIDs don’t match, it will stop the import. The purpose of this component is to transfer config between environments for a single site. Most should be familiar now with best practices but here is an example of what that would look like: development, quality assurance and production environment.
Learn by doing: Export new content type
I don’t know about you but I best learn by doing, so I want to step us through an example of exporting configuration from a new content type. Let’s add a new content type named, “News Update” with one new field “Date to Send”. Here is what that looks like in the UI:
Let’s see what we get when we run a configuration export:
At first, this may be pretty overwhelming but we are going to take it one step at a time. Let’s think about what we did in the UI. We created a new content type and added a new field. While we only did two actions, Drupal goes ahead and does several things behind the scenes. It will add a body field to all new content types as well as one form display and two view display modes. For this example, our configuration files fall into the following categories:
- Definition of node
- Definition of fields
- Definition of Node Display
It is important to get familiar with the format of these yaml files as when config files live in your VCS they are susceptible to merge conflicts. Let’s take a look at the node settings form and config and see if we can’t determine what each value means.
On the left we have the settings for the content type “News Update” and the right is the output of the yml file. Let’s go line by line in the yml file:
- UUID - specific identifier for database
- Langcode - Default language code
- Status - Whether or not the nodes are publish
- Dependencies - A majority of configuration will have dependencies to other modules, this is where that information is stored. This information is also used to determine in what order configuration can be installed. For example, “News Update” cannot be installed without the menu ui module.
- Third_party_settings - Settings for dependencies. This relates to the “menu settings” tab.
- Name - Human readable field for name.
- Type: Bundle
- Description - Description field
- Help - Help field.
- New_revisions - Create new revisions checkbox on “Publishing Options” tab.
- Preview_mode - Preview before submitting radio buttons
- Display_submitted - “Display settings” tab
Now truth be told, I didn’t know what all of those values meant off the top of my head but I knew the trick to figure it out. When configuration has a form that you can change values, those form’s fields have to have the same name as the config name. For each value I didn’t know, I searched the html source of the page and found the field it relates to. This is a great hack to figure out what maps from the front end to the database.
Setting up config workflow
This section will review how to get up and running with configuration management on your project and some of the gotchas when working with a development team.
- Confirm “Configuration Manager” module is enabled.
- Confirm in settings.php that $config_directories['sync’] is set.
- Confirm you have drush installed.
- Catalog any sensitive configuration you don’t want into version control.
- Configure your site to work with a local.settings.php (most hosting providers give instructions on how to achieve this in their environments)
- Make necessary overrides
- Run drush cex, for your first export this should be gargantuan (think Godzilla) , confirm that override values are not in config
- Create a PR and get a merge request for the updates.
- Either via manually or through a continual integration tool, release code to test environment.
- This steps should include
- Composer install —no-dev
- Drush updb -y
- Drush cim -y
- Drush cr
- The sync directory on a hosted env should be above web, this is a setting you can make local to the hosted servers
- This steps should include
- Voila you just tested your first config import
For those more visually inclined, here is an example with multiple developers:
Summary and further learning
From this article, you should have a good understanding of how configuration management works in Drupal 8. We have gone over examples of how to export the configuration for a new node and dug into what actually makes up the config yaml files and how they relate to fields in the UI. Finally, we went over an example of possible development workflow with a team of developers, VCS, CI and hosted environment.
This is just the tip of the iceberg when it comes to configurations management. f you are looking into ways to have content exportable to other environments like config, I suggest looking into the yaml_content module, maintained by Mediacurrent. If you are looking for the newest modules to help manage edge cases within configuration management, give Anthony’s Configuration Management Part 2 a read.