Drupal Features Module 101
General intro to Features
A quick show of hands… how many of you are using Features? Now, how many of you are using Features to manage deployments? (assumes similar number of hands). How many non-techies would like to know how Features would improve their Drupal site? (good, that's my next post).
But for all of us geeks, even though the original intention of Features was to create features (shocking), it's no longer necessarily priority number one for this module. A good portion of this issue will be addressed with the Configuration Management Initiative, but for existing Drupal 6 and 7 sites, Features is your best bet. For the unfamiliar, Features is a freely available contributed module that allows a developer to export parts of his or her site’s configuration to code that is typically stored in the database. Think of Features as a package, inside it might contain multiple items like Views and Content items. This package is easily transportable since it wraps all the smaller items in the easy to use Drupal module system without having to write any code. Now, when it comes time to deploy this feature to a production website, its a simple matter of enabling the feature and away you go. As an additional bonus, since your configuration is now in code, changes can now be committed to your version control system (you are using a VCS, right?).
Features via Drush
Another wonderful feature of Features, is that the module has solid integration with Drush. The four major commands typically used are - features-list, features-diff, features-revert, and features-update. Each command is executed from the command line via `drush` (e.g. drush features-diff demo_feature). The commands can be replaced by their aliases, which I’ve listed immediately after each command.
- features-list (fl) - Provides a list of all the available features in your site, their status, and their state. Status will either be 'enabled' or 'disabled'. State could be ‘blank’ (default), ‘overridden’ (code and database differ), or ‘needs review’ (state cannot be determined).
- features-diff (fd) - In order to use this command, you will need to install its dependency, diff. When executed, this command will display the difference between code and the database. Running drush fd is a good precursor to our next commands, features-revert and features-update.
- features-revert (fr) - If you don’t like the changes presented by the previous command and would prefer to go back to how things originally were, simply run the revert command and your database will be updated with what’s in code.
- features-update (fu) - However, if the results are as you like, run the update and your feature module’s code will be updated to be in sync with the database. Commit your code changes and you’ve officially versioned your feature. Easy peasy.
Now, for the warnings. Once you have your brand spankin’ shiny new feature, you’ll need to enable it. Be forewarned that this entails deleting the existing components of the feature (content types, views, etc). Which, in turn, means that you could possibly lose any existing data of that type (or put your nodes in node limbo). The correct order to create your feature is as follows:
- Create your feature components (content type, view, image styles, roles, etc.)
- Create your feature comprised of those components.
- Delete your components.
- Copy your feature to your modules directory and enable it.
- Create your content.
So, please be sure to create your feature early on instead of later after content is created.
To reiterate, it is extremely important for you to remove the existing features’ components before enabling your feature. As I recently found out, this can lead to some annoying issues. In my particular situation, I had forgotten to remove a view before enabling the feature. When I looked at my list of features, my new feature was constantly in “Overridden” state. No level of feature reverting or updating would resolve this. It wasn’t until I had disabled the module, realized that the view still existed, deleted it, then re-enabled the feature before I was able to get it back to “Default” state. Please, be sure to do this so you don’t end up frustrated and disliking Features.
Another important thing to look out for is keeping your features separate. Do not cross the streams! If you have a content type in a feature that is sharing fields with another cont ent type in another feature, you will experience issues. Be sure to create separate fields for each content type. Another example would be as follows. Create a feature with a view t hat references a content type in a second feature. Then, in the second feature, add a context that references the view in the first feature. Since the view can’t exist without the content type, and the context can’t place a view that can’t be built... Drupal will get angry. And you won’t like it when it’s angry.
With the coming of Drupal 8’s Configuration Management Initiative, I believe the Features module will revert back to what it was originally intended for, instead of a makeshift deployment tool. Speaking of which, I’m sure the fine folks from that initiative would love a hand. See you in the issue queues!
Webinar: The Power of Maps and Drupal.
Webinar: Drush Site Aliases
What is Drupal? | Mediacurrent Video