Introduction
Management of site settings has been a challenge ever since the early days of the Drupal project. What is managed as configuration is often difficult to differentiate from the content. General site information is not the same as taxonomy vocabularies, terms, menus, or blocks.
Earlier versions of Drupal store a variety of settings as variables which are managed with variable_get()
, variable_set()
and variable_del()
functions.
Drupal 8 comes with a new configuration management system that unifies storage and retrieval of configuration data centrally. It provides a set of APIs that custom modules can leverage in the same way as the core.
The new system covers the following:
- Simple configuration (Config API) — Settings that require synchronization between different environments, e.g. site name, slogan, user account settings, etc.
- Local configuration (State API) — Settings that are more transient or subject to change and which should not be synchronized between environments. e.g. the last cron run, the timestamp for statistics, last update time, etc.
- Complex configuration (Configuration Entity API) — These are more complex things or entities that require manipulation in the manner of create, edit, and delete. For example, user roles, views, fields, filter formats, etc.
CLI Interaction
We are going to use DrupalConsole, and we recommend our Introduction to DrupalConsole article for an overview of this excellent CLI tool for Drupal 8.
Config API
Let us interact with our simple configuration settings by viewing them first:
drupal config:debug
Some settings are more complex than others. You can get quick access by debugging them by the name of their key. For example, system.site
settings:
drupal config:debug system.site
You can change the value of the name
key with drupal config:override <name> <key> <value>
command:
drupal config:override system.site name "My Demo D8 Site"
After that, debug system.site
settings to see the change.
State API
We can also interact with our local configuration similarly:
drupal state:debug
These settings are simpler than the configuration settings we saw earlier. Checking the maintenance mode of our site is easy:
drupal state:debug system.maintenance_mode
To take the site down, we use the familiar override command, drupal state:override <key> <value>
.
drupal state:override system.maintenance_mode true
You can revert that by overriding it back to false
.
Code Interaction
In code, you have full access to the APIs provided by the configuration management system.
Config API
There are two types of Config
objects — a read-only instance (immutable) and a read/write one (mutable). They can both be retrieved directly from the service container:
$immutableConfig = \Drupal::service('config.factory')->get('system.site');
$mutableConfig = \Drupal::service('config.factory')->getEditable('system.site');
This gives access to all the settings under the system.site
key, i.e. in the system.site.yml
file. You can also retrieve any subkey, and the calls are chainable.
$name1 = $immutableConfig->get('name');
$name2 = \Drupal::service('config.factory')->get('system.site')->get('name');
To edit, call the set()
method:
$mutableConfig->set('name', 'X-Team Drupal 8 Demo');
\Drupal::service('config.factory')->getEditable('system.site')->set('name', 'X-Team Drupal 8 Demo');
Finally, you can save the changes:
$mutableConfig->save();
If you recalled that the functions are chainable, you could have done this:
$mutableConfig->set('name', 'X-Team Drupal 8 Demo')->save();
While all this may be well and good, usually, you need configuration settings in classes, and the recommended way is through Dependency Injection. In your class, implement Drupal\Core\DependencyInjection\ContainerInjectionInterface
interface and inject the container service. Then, you can do something like this:
$this->container->get('config.factory')->get('system.site');
Or, after injecting the config.factory
service itself:
$this->configFactory->get('system.site');
State API
This is similar to Config API but simpler. To read, get the State
object from the container and call the get
method on it. The argument is the name of the key
for the setting to be read.
$offline1 = \Drupal::state()->get('update.last_email_notification');
$offline2 = $this->container->get('state')->get('update.last_email_notification');
As you can see, this is also mutable and chainable. Remember that this is for storing volatile environment-specific data. It should not be part of the deployment process.
To edit, call the set()
method:
\Drupal::state()->set('update.last_email_notification', REQUEST_TIME);
It gets written to the key_value
table in the database:
select * from key_value where name = 'update.last_email_notification';
+------------+--------------------------------+---------------+
| collection | name | value |
+------------+--------------------------------+---------------+
| state | update.last_email_notification | i:1498205343; |
+------------+--------------------------------+---------------+
To delete:
\Drupal::state()->delete('update.last_email_notification');
Conclusion
In Drupal 8, information is classified into content, session, state, and configuration types. In this short article, we have looked at how to interact with configuration and state types.