Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Configuration Management and Features: a look at Drupal 8

Parent Feed: 

What CMI will bring to D8 and "Poorman's Features" for packaging configuration in D8

An update to this post is now available at http://nuvole.org/blog/2014/jul/15/packaging-and-reusing-configuration-d....

We have always told attendees of our Drupal 7 "Code-driven development" trainings that embracing the idea that configuration must be stored in files and not in the database would make their Drupal development future-ready: the specific processes would necessarily change but the concept would stay and be reinforced in Drupal 8, thanks to the nice work being done in the Configuration Management Initiative.

And this was right. The progress done in CMI is very good, to the point that in our coming DrupalCon training in Prague, Code-Driven Development: an Effective Drupal Workflow, from D7 to D8 we will explore in detail how things work in Drupal 7, but for each topic we'll also describe what is going to improve/change in Drupal 8.

Configuration Management in a nutshell

From a site builder's point of view, Configuration Management in Drupal 8 is visible as two items in admin/config/development: "Configuration Export" and "Configuration Import".

The Export functionality has no further options, and it provides you with a config.tar.gz file containing hundreds (180+ on a clean installation, many more on a feature-rich test site) of files in YAML format, human- and machine-readable. All the site configuration is there: node types, their fields, permissions, Views, theme settings, variables...

The Import functionality, on the converse, will import a config.tar.gz file, show you any configuration changes between the currently active configuration and the one you are trying to import and allow you to replace the current configuration with the one in the provided files.

config-import

For many developers, this is a dream come true: with D8, Drupal Core will support a file-based configuration, allowing developers to track changes, put configuration under version control, update a production site cleanly... basically, all the advantages that we have described as selling points for the Features module in the last several years.

The Future of Features

So, if the major selling points of the Features module are now in core, does Features have a future in Drupal 8?

It still does, but it needs to be repurposed. So far, it had a dual functionality, serving as:

  • A machinery to export/import configuration from database to code. This will no longer be necessary in Drupal 8. Configuration lives in files and the database is used only for caching. For the same reason, an important problem in Drupal 7 development ("How do I make configuration exportable when there is no native support for Features?") is now solved for good.

  • A convenient way to package and reuse configuration across multiple sites. This is extremely useful to developers and not completely covered by Configuration Management in Drupal 8, even though the basic components are there.

Poorman's Features: emulating Features in Drupal 8

Let's see how it is possible to package configuration and emulate, manually, what Features and Drupal 7 allow today.

As an example use case, we will package a "Blog Feature".

1: Create and export configuration

Create the Blog content type, configure its fields (use proper naming for fields: field_blog_image and so on) and a classic view with a block and page display. Then go to admin/config/development and export your configuration into the config.tar.gz file.

2: Package relevant configuration into a module

Create a simple feature_blog module containing:

  • feature_blog.info.yml: a basic .info file in the Drupal 8 format.

name: Blog
type: module
description: 'A Blog content type and related configuration.'
package: Features
version: 8.x-0.1
core: 8.x

  • feature_blog.module: an empty module file, needed for correct Drupal operations.

<?php
  // Drupal needs this empty file.

  • a config subdirectory: copy to this folder all relevant files from config.tar.gz; filenames are quite helpful here, as it will be enough to copy all files that have "blog" in their name.

.
|-- config
|   |-- entity.display.comment.comment_node_blog.default.yml
|   |-- entity.display.node.blog.default.yml
|   |-- entity.display.node.blog.teaser.yml
|   |-- entity.form_display.comment.comment_node_blog.default.yml
|   |-- entity.form_display.node.blog.default.yml
|   |-- field.field.field_blog_image.yml
|   |-- field.instance.comment.comment_node_blog.comment_body.yml
|   |-- field.instance.node.blog.body.yml
|   |-- field.instance.node.blog.field_blog_image.yml
|   |-- node.type.blog.yml
|   `-- views.view.blog.yml
|-- feature_blog.info.yml
`-- feature_blog.module

3: Make the exported files portable (remove UUIDs)

The feature is ready, but it will only work if imported in the same Drupal 8 site. We need to make it portable to other sites.

The main problem here is that Drupal assigns UUIDs (Universally Unique Identifiers) to each component. When you add, say, an "image" field to a content type, you create an instance of the "image" field, and to describe this relationship Drupal will rely on the UUID of the "image" field. Since UUIDs are site-specific, trying to import this configuration on another site would result in an error message like:

Drupal\field\FieldException: Attempt to create an instance of
unknown field 84e904df-2f14-46e8-9700-e00c5ca3f7d3
in Drupal\field\Entity\FieldInstance->__construct()
(line 252 of .../core/modules/field/lib/Drupal/field/Entity/FieldInstance.php).

Fortunately, in this case configuration import is designed to accept either names or UUIDs for describing the field this is an instance of. So it is enough to edit all files containing field.instance in their name and manually replace UUIDs with machine names (or just add machine names), something like the following:

-field_uuid: 84e904df-2f14-46e8-9700-e00c5ca3f7d3
+field_name: field_blog_image

Note that this relies on the specific handling of the FieldInstance class and may not be a general solution.

Edit: also note (see comments) that it is important to include a hardcoded UUID if you want to avoid that your configuration items are seen by Drupal as different items between your development and production sites, causing configuration import/export between the two to fail.

4: Import the feature on another site

Our module/feature is now ready to be imported. Just copy it to the /modules folder on another site, or a subfolder of it (this is now the recommended location to add modules) and enable it.

Your content type and configuration will be immediately available.

Possible improvements

The Configuration Management in Drupal 8 will bring to Drupal Core a clean, unified, professional way to deal with configuration. There will still be the need for a module like Features for packaging and reusing configuration.

Some implementation details of Configuration Management do not behave well in this respect: for example, UUIDs are problematic and user permissions are stored in a packaging-unfriendly way (one file per each user role, with roles identified by UUID).

But, overall, the future looks bright and code-driven! And, as we have seen, it is already entirely possible to manually create basic "Features" (i.e., modules with configuration) that will work in Drupal 8.

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web