Features Part 2 - Managing your feature
In the previous post we built a basic blog feature. This post will cover details on how to manage that feature (i.e. update, revert, etc.).
You don't need much to get going with this, but what you will need is:
- Read through the previous post and can build a feature
- Basic use of Drush and the command line
I'll cover drush in more detail in a later set of posts, but for now it's important that you install Drush if you haven't already. Features includes a set of Drush commands that are used to update and maintain each feature. These links should help get you started with Drush:
Note that if you're doing this on a D6 site, the Drush 7.x version will work. Drush is not a module in the traditional sense, and it's Drupal version agnostic.
If you browse back to the features admin page (admin/structure/features) the example blog feature should be enabled (enable it if it's not). Features will take notice of any changes you make to any of it's components and tell you they've been "overridden". Due to some of the things that one can do with features, the terminology can occasionally get a bit ambiguous, so it's probably important to define a couple of the terms used:
- Default (state): All settings in your feature identically match their respective settings on the site (this is the state you're after :) ).
- Overridden (state): The components of the feature used in the site no longer match the state of them in the feature module. For example, if you were to use the Views UI to change the number of blog posts listed on a page from 10 to 15, your feature would now be overridden as your site is displaying 15 posts, but your feature module specifies 10 posts.
- Needs review (state): This is effectively the same state as overridden, but generally means there are more complicated changes and it's recommended you review the differences prior to reverting the feature.
- Revert (action): You can revert an overridden feature to make the site settings match those in your feature module. In the above example you set your site to show 15 posts instead of 10 posts in a blog listing. If you decide that you no longer want that simply revert the feature and you'll be back to 10 posts. Revert is probably the most confusing term used with features.
- Update (action): Updating a feature is the exact opposite of reverting one, instead of reverting your site to match your feature, you'll update your feature to match your site. In other words, if you prefer to have 15 posts lists, update your feature to bring it back in sync. This will change the setting from 10 to 15 posts in your feature and take your feature back to a default state.
Diffing a feature
So let's give the above a try. Change the display settings on your blog listing view to show 15 posts instead of 10 this will mean our blog feature will no longer be in sync with the settings on the live site. Back on the features listing page you should see that your blog feature is now "overridden".
Click the overridden link to bring you to your full feature page.
The above image shows that the overridden component is "views". If you've enabled the Diff module, the word overridden will link to a diff between your site and your feature (the "review overrides" tab will also give you the same thing).
Reverting a feature
After reviewing the changes, if we've decided we don't like the changes (perhaps another site admin made them, after all), we can revert the feature. Simply select the components you wish to revert (in this case only views) and click the "Revert components" button.
Your site will now be reset to match the code in your feature module and display 10 posts again instead of 15. I've occasionally experienced caching issues where the component is still listed as overridden instead of default as it should be. Flushing caches should sort this out.
Updating a feature
Ok, you've changed your mind now and do actually want 15 posts displayed on your blog listing. Head back to views and switch the number of posts to display to 15.
We now want to sync up the features code so that it matches the site. This way when we take the feature to new sites it will also show 15 posts.
On the command line change to your site folder for this site (sites/default perhaps). Run the command:
$ drush features-update example_blog
example_blog should be replaced with whatever you named your feature.
Features and Drush
Though updating your feature is the only thing Drush is required for, you can perform any feature management actions directly in the command line.
drush help shows the following commands:
All commands in features: (features) features-diff (fd) Show the difference between the default and overridden state of a feature. features-export (fe) Export a feature from your site into a module. features-list (fl, List all the available features for your site. features) features-revert (fr) Revert a feature module on your site. features-revert-all Revert all enabled feature module on your site. (fr-all, fra) features-update (fu) Update a feature module on your site. features-update-all Update all feature modules on your site. (fu-all, fua)
We've diff'd, exported, listed, reverted, and updated our feature now, which covers all the bases for feature management.
I can't stress enough the importance of keeping your site in sync with your features. If you're lazy and your features are perpetually listed as overridden you're going to be in for a world of hurt. This is particularly true when using a
dev -> stage -> prod workflow with features or working with multiple site builders at one time.
NEVER have two different developers working on the same features components at the same time. For example, if developer A updates a view in the blog feature and then updates their code from developer B who updated a different view in the feature, developer A will need to redo their work after reverting the feature. This is equivalent to two developers working on the same line of code in the same file at the same time. There will be conflicts. With that said, it is possible for Developer A to update the content type while Developer B updates a view.
In a simple workflow you'll update the feature in your local dev environment, then push the changes to stage, revert the feature on stage (this is where the ambiguity of the terminology really comes into play :)), test, push to production, revert the feature on production, test.
Make as few changes as possible to the feature on the live site, i.e., even configuration updates should be done locally first and pushed out. This way you'll be less likely to break the live site and you won't run into nasty conflicts with your features as you develop the site.
What if you want to use the same feature on two sites, one which will display 10 posts in the listing and the other 15? This is where "fully" re-usable features come into play. Instead of forking your feature it is possible to give them settings of their own. I'll be going into more detail on this in my the third post on features.