Skip to main content

Managing Shared Configuration Part 6: Packaging Configuration with the Features Module

Authors
September 24, 2018
Body paragraph

This is the sixth installment in a series presenting work on shared configuration that comes out of the Drutopia initiative and related efforts, beginning with Part 1, Configuration Providers.

Our main focus has been updating configuration from distributions--specifically, the question:

How can I update my site so that I have all the latest configuration changes from a distribution--while still retaining any customizations I made?

Updates are well and good. But before packages of configuration can be updated, they need to be produced and managed in the first place. In Drupal 8 as in previous major versions, that task is the domain of the Features module.

The Drupal 8 version of Features is a complete rewrite with major improvements over previous versions. If you're familiar with previous versions but haven't used Features in Drupal 8 this backgrounder will bring you up to speed.

Despite being a development-focused tool, Features is in the top 40 or so most installed contributed Drupal 8 modules. Features is used in building and maintaining several of the more-used Drupal 8 distributions including Open Social, Varbase, Open Church, and Quick Start. It's a key build tool for the Gitlab-hosted Drutopia project.

In this installment we'll cover Features in Drupal 8, including how to use it to produce a distribution.

Analyzing the site

With its default configuration, Features will automatically divide a site's configuration into a logically structured set of distinct features. It will even generate an installation profile to use with the set of features.

Features is architected around three main components.

  • An assignment plugin influences the way that configuration on a site is assigned to distinct packages or features. Features ships with a large set of assignment plugins and other modules can provide their own. See documentation on Features assignment plugins and related developer documentation.
  • A generation plugin determines how features are generated. Features ships with two generation plugins, one that creates downloadable archives and the other that writes features directly to the file system. See documentation on Features generation and related developer documentation.
  • A features bundle is a configuration entity that defines a set of features such as those included in a specific distribution. Each bundle has an associated set of assignment plugins configuration--so each distribution can customize the way its configuration is packaged. See documentation on Features bundles.

The easiest way to get a feel for this functionality is to install a fresh Drupal site and then use Features to turn it into a distribution.

Here's how.

Install Drupal and enable the Features UI module

One quick way is to use simplytest.me:

  • Bring up simplytest.me with the Features module preselected and click "Launch sandbox". This will spin up a site installed with Drupal core's "Standard" installation profile.
  • When the site loads, if you have not been automatically logged in, click the "Log in" link and log in with the user name "admin" and password "admin".

Alternately, install a local development site using the "Standard" install profile. See Chapter 3 of the Drupal 8 user guide for details.

When you have a site installed and are logged in as an administrator:

  • Click "Extend" and install the "Features UI" module.
  • Navigate to admin/config/development/features and click the "Configure bundles" tab to bring up the form for creating and editing feature bundles.
  • For "Bundle", select "--New--" and enter the bundle name "Exemplary".
  • Check the checkbox "Include install profile" and enter "exemplary" for "Profile name".
  • Click the "Features" tab to bring up the form for downloading features. You'll see that the site configuration installed by the "Standard" installation profile has been neatly divided into several distinct features. As well, an installation profile, "Exemplary" has been created.
  • Click the checkbox in the table header, left of "Features", to select all available features.
  • Click the "Download archive" button.

What you get is an initial draft of a Drupal distribution. You can copy the resulting directory and all its subdirectories to the profiles folder of a Drupal codebase and install a new site using the "Exemplary" installation profile.

Of course, you won't get anything that's not already in Drupal core's "Standard" installation profile. But there are two advantages you get from the exercise:

  • You can easily install just a subset of what Drupal core provides. This contrasts with the "Standard" profile, which installs everything all at once, whether or not you need it on the particular site.
  • You have a base to build on. As you continue to build out new elements on your site, following the naming conventions in the Features building workflow, Features will recognize new features as you build them and, again, automatically package them into feature modules for generation.

Features and dependencies

The "base" and "core" assignment plugins give a feel for how assignment plugins work together to assign configuration to features.

The Base assignment plugin

To automatically divide a site's configuration into distinct features, we have to know what features to create.

One way is by analyzing the configuration itself. Certain types of configuration have a whole lot of other configuration that depends on them. Content types are a key example. A content type doesn't require any other piece of configuration, but typically has many pieces of configuration of different types that depend on it: fields, view modes, search indexes, and so on. For that reason, it's often a good design decision to create a feature module per content type on the site.

That's what the base assignment plugin does: takes a particular type of configuration and created a feature for each item of that type. Concretely, on a site that has an event content type and an article content type, the Base assignment plugin will create an event and an article feature. Then it will assign to that feature every piece of configuration that's namespaced with the feature name. For example, a field called field_event_type would be assigned to an event feature.

The Core assignment plugin

The core assignment pugin addresses the problem of configuration that's required across multiple features. How do we provide that configuration without creating a bunch of cumbersome inter-feature dependencies?

Say we have a tags field we use on both an event content type (provided by our event feature) and an article content type (provided by our article feature). Like all fields, the tags field has an accompanying field storage. That means the tags field storage will be required by both the event and the article features.

If we put it in the event feature, the article feature will require events--which doesn't make sense. The reverse case - that events require articles - isn't any better.

The Core assignment plugin addresses this issue by pulling specified types of configuration into a core feature that can be required by other features.

Further reading

See the blog post How to use Features module in Drupal 8 to bundle functionality in reusable module for an introduction to the module. There's also a detailed Features 8 handbook on drupal.org.

Potential enhancements

While Features in Drupal 8 is mature and used on thousands of sites, there are loose ends and some significant missing pieces still to cover, and additional uses the module could be extended to.

Translations

Drupal 8 supports multiple "collections" for configuration. So far, Features only works with the default collection. In practice, this means most configuration is handled fine, but language translations of configuration are not. Here's the relevant issue: Support non-default configuration collections, including language.

Alters

A significant missing piece is integration for alters (covered in Part 4 of this series).

There are two parts to integrating support for alters into Features. First, when exporting items to a feature, it should be possible to export specific changes as alters. Second, in the export of the original item, any alters should be reversed, so that the exported item is alter-free. Core's configuration override system includes the ability to load configuration free of overrides, but there is no equivalent as yet for the various approaches to altering configuration-provided configuration. Potential pieces to help address these requirements include:

Additional use cases

The plugin-based architecture of Features means it can potentially be applied beyond its original use case of managing feature modules. For example, it would be relatively simple to provide a features generation plugin to generate configuration packages as Configuration Split configuration entities.

Related core issues

Next up

Stay tuned for the next installment in this series: Base Configuration.