If you’re reading our Drupal tech posts, Beaconfire RED is hiring and we want to talk to you! Come join our tech team in 2017 and play with Drupal 8!
This is a guide to setting up the Features module and how to organize a site’s Features. In particular, it focuses on the basic setup and the inclusion of Content Types.
Features is meant to be a development module. It shouldn’t be needed on production but, if installed, should have the UI disabled. The intended usage for Features in Drupal 8 is to use Configuration Management (CMI) to export configuration changes to and from prod. One major reason for this is that Features in Drupal 8 doesn’t have override protection. So there’s no lock icon to say, “leave this overridden part of the Feature’s configuration alone on this site.”
What makes a Feature? In Drupal 8, the only thing that differentiates a Feature from a normal module is the inclusion of the *features.yml file in the module folder. Removing this file disconnects the module from Features but keeps it available on the site.
Here is an early overview session by Mike Potter, maintainer of Features: https://www.youtube.com/watch?v=CfnIThkBAFM
Folder location: Note that, currently, Features will be automatically generated in the /modules/custom folder. This reflects the state of generated Features as standalone modules. Therefore, you’ll want to make sure to use a custom Features Bundle to control prefix something to their folder names to help you keep things organized and avoid namespace conflicts.
Evolution: Also, note that this reflects the current state of Features and, like most things in Drupal, there are different ways to achieve the same result. This approach works but will likely need to evolve over time as the Features module and Drupal 8 evolve.
Versions: For reference, this was written while running Drupal 8.1.8 with Features 8.x-3.0-beta7.
There is a dependency on the order in which the Features are created. What’s happening is that newly created Features auto add their dependencies based on whether or not another Feature has already included this. So, for things like shared fields, this can be a little confusing. It can result in configuration that is split up across multiple Features in unexpected ways.
Also, adding some things, such as Entity Display modes, to a Feature can result in a Feature that cannot be enabled. The workaround for this is to move these to the “Optional” category. This results in the YML files being in an “optional” subfolder for that Feature and allows the module to be enabled. The Setup Guide below will show you how to set up the Features Bundle to make this happen automatically. Currently, there is a ticket to make the “Unmet Dependency” errors more informative, but that is a Drupal Core issue, not a Features issue: https://www.drupal.org/node/2655104.
Note that the auto dependency system can be disabled or circumvented. The approach suggested here keeps it enabled as it’s useful. You just need to make sure to set up your Features and their Components in the correct order.
Shared Components in the “Core” Feature Versus Separate Features
The “Core” Feature, should contain, among other things, configuration that is shared by multiple Features. For example, content types can reuse a field. However, while each content type has its own field settings, they all share the same Field Storage. This particular example is only relevant if the fields will be shared by multiple content types.
The method suggested here is to only include field storage (and other shared components) in the “Core” Feature. Then, include the fields themselves (which are associated with a content type) in another Feature. This can be a little confusing, though, as adding something to the “Core” Feature runs the dependency check again. So it would auto select all the newly added content type configuration Components. Then, you’d be unable to add them to the Content Type specific Feature.
Alternatively, you could keep all Field related Components in a single Feature, either “Core” or a “Content Types” Feature. Either way, the critical step is to pay attention to the order in which the Components are added to the Features. You want to prevent unintentionally splitting up related Components and then having the auto-dependency system prevent you from making changes.
If you want a content type’s Feature to contain all the Component configuration info for that content type, then the content type’s Feature must be created before updating the “Core” Feature. So, in general, you’ll want to create your Features in a certain order and optionally remove some configuration components during their creation.
Here is a quick overview:
- Create a custom Features Bundle with the settings mentioned in the guide below
- Create a “Core” Feature and remove all content type related components (to avoid auto-selected dependencies)
- Create a “Site” Feature (leaving out things that you expect to be moved to their own Feature)
- Create a Feature for each content type (leaving out the Field Storage if this field will be shared by other content types)
- Edit the “Core” Feature and add the Field Storage Components for the new fields
This is the detailed list of steps to get a functional and understandable Features initial configuration. It assumes that you will break out your Content Types into their own Features while maintaining a “Core” Feature for shared Components.
- Enable the Features and Features UI modules
- Go to the Features admin page Configuration > Development > Features
- Configure Bundles and create a project specific one
- The Bundle will define the namespace for the Features and provide some pre-configuration options
- This provides a custom package name to group the Features on the module Extend page
- Use a short machine name as this will be prefixed to the module folder names
- The default settings should be fine with the following changes:
- Base type
- Remove Paragraphs if this module is in use on the site.
Currently (2016-8-18), all other Paragraphs Component configurations get auto added to the Core Feature and cannot be reliably removed. This makes it tough to break them out into their own Feature even though this appears to be a supported use case.
- Decide if any of these are things you’d like to have automatically broken out into their own Features, i.e. one per Taxonomy Vocabulary type or per Contact Page, etc.
- Remove Paragraphs if this module is in use on the site.
- Base type
- Core type
- Include “Paragraphs Type” in the Core.
- Make sure Remove “Entity form display” and “Entity view display” are unchecked.
- Optional type
- Set “Entity form display” and “Entity view display” to be optional. Otherwise, when enabling a content type Feature, there will be an unmet dependency error for the form and display view modes.
- Optionally, create a Feature to contain the new custom Bundle. Otherwise, you’ll need to migrate the Bundle settings to new dev environments manually.
- You don’t want to include the Features Bundle in the Core Feature because the Features module should not be a dependency.
- Export desired generated packages by clicking on their name in the un-exported packages area
- General info for all Features
- For the name and descriptions, add something to help show that this is a Feature. While they will be grouped under the Bundle name on the Extend page, they are not grouped on the module Uninstall page.
- Set the Bundle to the correct one
- Add a version and increment it when making a change to the Feature. This can be really helpful when trying to see if a Feature has been updated on the Staging site.
- Allow conflicts: Typically, leave this unchecked, however, it is useful to let you see what other Features are using the various configuration settings. They will be highlighted in bold red.
- General info for all Features
- Click on “Core”
- Don’t add the Bundle to this Feature as that shouldn’t make it out to production
- Deselect all Components related to something you’d like to have in another Feature, i.e. Entity form and View Displays, Fields, and Field Storage. Do this from top to bottom to avoid auto-selecting Components again.
- Add the Paragraphs
- Click on “Site”
- Deselect options you will add to a separate Feature, such as a contact form that will go on a Page, etc.
- Click on each Content Type
- At this point, the default should work correctly.
- This should include the following Components for this Content type (they should be preselected)
- Content Type
- Entity form display
- Entity view display
- Deselect shared Components that will be added to the “Core” Feature, for example:
- Field Storage
- Paragraphs type
- Edit the “Core” Feature again
- Add the shared components that were previously deselected from the other Features.
- At this point, the other related Components should not be automatically added.
- Enable your new Features to verify they install correctly
- From the Extend menu, find your new Features and enable them like other modules. If you followed these steps, they should be in a group with the same name as your custom Features Bundle.
Moving Existing Configuration Components from Core to Another Feature
This can be challenging because, by default, creating the Core Feature will automatically reapply related/dependent configurations even if they are handled by another Feature. To resolve this,
- Create or edit a Feature
- Check the option “Allow conflicts”
- Add the configuration Components desired for that Feature (i.e. Fields and Displays)
- Save the Feature
- Edit the “Core” Feature
- Uncheck “Mark all config as required” in the Core Feature and write or Download the Feature
Some configuration Components may not be removable from Core if dependencies exist, i.e. if Paragraphs field storage is in Core, most (but not all) of the other Paragraphs configurations get auto selected. This could be an issue with a misconfiguration of the Bundle or it could be a quirk. These sorts of things come up which is why it’s best to try and follow a set order during the creation of your Features.