Today I'm giving two workshops at DrupalCamp Stockholm. One is about the Context module and the other about the Features module. This article serves as documentation for the second workshop on the hot topic of Features.
There is a lot of buzz around Features in the Drupal community at the moment. They're the next big thing: Everybody wants one, but they are still a little hard to come by.
So, what is a feature? The one sentence definition on the module page says it well:
A feature is a collection of Drupal entities which taken together satisfy a certain use-case.
In this workshop, we will explore the Features module using a couple of hands on examples. But first, let's talk about the concepts behind it in more detail.
A collection of exported building blocks
A feature is some generic functionality that can be reused on different websites and that consists of exportable Drupal building-blocks, for example Content types, Views, ImageCache presets and Context. A feature could be a blog, an image gallery or a more complex structure of exportable building-blocks. By "exportable building-block", we mean something that can be exported to code and hence can live outside the scope of a database.
The beauty of features is that it is reusable and it keeps track of its own status; a feature knows which modules it is dependent on and whether it has been modified since it was installed. And since features are in essence modules on their own, you can easily add to or tweak a feature's functionality to suit your own needs. Some extra goodies is that features work well with Drush and that they can easily be shared with other Drupalers with the help of feature servers, more on that further down.
Anatomy of a feature
Again, a feature is in essence a module, with some specific twists. The actual .module file is more or less empty. Instead, much of a feature's structure is defined in its .info file, using a couple of Features specific keywords that define its components. The actual data, such as the settings of a view or a content type, is stored in separate files, as seen above.
Your first feature
Another way of approaching Features is to take an existing ad-hoc "feature" on a Drupal site and create a proper feature out of it, using Feature's Create feature page. It's surprisingly easy!
First, we need to set up a testing site. If you followed the previous workshop you already have everything you need. If not, you can fetch the downloadable file archive here. Once you have it downloaded and unpacked, you'll find an SQL dump named features_starting_point.
Now, go to Administer -> Site building -> Features -> Create feature. You'll see a form like the one above. We will create an image gallery feature, so fill in the name and description as shown above. You can leave Version empty, and the Update URL too. (The latter is used for when you use a Feature server to publish your features.)
Next, take a look at the Add components section. The drop down menu on the left contains all the basic types of entities that you can include in your feature. (In the image above, the menu has been repeated in order to save some screen space.) The image gallery uses one node type, one context, one view and three imagecache presets. In the screenshot above I have only selected one imagecache preset, and no views. You can see in the table to the right that Features caches them anyway, since the node type and context already depend on them. You'll also see that Features also has figured out that the image gallery requires the modules context, features, imagecache, imagefield and views. They then depend on other modules like ImageAPI, but that's handled by Drupal core's module system.
Finally, click on the Download feature button. A file named image_gallery.tar.gz will get downloaded. When you unpack it you'll find a folder containing the same files as in the screen shot above. If you want, take some time to look around in these files and see if the code makes any sense to you.
Deploying a feature
Now, let's move on! It's time to move the image_gallery folder into the Drupal installation so we can take it for a spin. Put it in the
sites/default/modules/ directory and then go back to Administer -> Site building -> Features. Like magic, your feature has already found its way into the list of installed features.
Because this feature consists of components that are already defined on this site (view, context etc.) it's currently not possible to effectively switch this feature on and off. It will be impossible to switch off, because the components exist independently of the feature. We need to delete all those components in order to see how this feature behaves in real life. Go through and delete the following items:
- The gallery view.
- The gallery context.
- The Imagecache presets large, mini_thumbnail, and thumbnail.
Don't delete the Image content type. If you do, all existing images will disappear.
Your image gallery page should be gone now though. Go back to the Features page and activate the Image gallery feature. If everything works according to plan, your image gallery should be fully restored. If you want you can try disabling and enabling the image gallery again! It's amazing to see how a complete section of the site can be just switched on and off like that!
Now, for homework you can create a second feature of the News section on the test site. Just repeat the steps from Your first feature onwards.
Keeping track of local changes to installed featues
Again, features builds upon standard Drupal components like views and CCK fields. What about if you change one of the components that belongs to a feature? Features comes prepared for such overridden components. If you go to the gallery view and for example change the title of one of the displays, you will see that the Features page will show the Image gallery features as overridden. If you have the Diff module available (which the test install has) you can click on the overridden link and see a summary of what parts of the feature has been changed, expressed as a diff on the exported component code. If you decide you want to go back to the original version, you can click the Revert tab. Here you will be offered the choice of reverting just the components you want.
Third party features
Now, one of the great benefits of Features is that they're easy to share. Let's say we want to make a user blog feature on our site, and instead of building it from scratch, we will use the Blog feature that comes with the Spaces module. This description will be kind of brief, so you may have to explore some of the details on your own.
Begin by activating the Spaces blog features. Before we can make proper use of the feature, we need to activate the Spaces user module to give us a user oriented space for this feature. (The Spaces module is out of scope for this workshop, but it provides a convenient way to use Features, so we'll use it here.)
Once the appropriate modules are available, you can go to Administer -> Site building -> Spaces and create a space preset for user spaces. Make sure the Spaces blog feature is active by default.
Now go to your user's (admin's) user page. Right now there is no convenient link to that page, so go to the path
/user. You should see a Features tab, which allows you to decide which features are available in this space. Make sure the blog feature is activated and then go back to your user page. There is now a "View recent blog entries" link, which takes you to your personal blog page. Try adding a blog post and see how everything behaves.
This is just a quick example of how you can use Features and Spaces to activate your own or third-party features on your site. A more elaborate example is the Open Atrium project, which is a complete project information system built with Features, Spaces and Context among other things. I recommend downloading Open Atrium to get a real feel for these modules' potential.
Feature servers are a method of publishing and distributing features to many client sites. Updates that are made on the server are distributed automatically to the client sites. Feature servers can form a decentralized structure where many servers are used to provide features to single web sites. One benefit of this is that it's possible to focus on narrower use cases than is the case with modules published on drupal.org, as they need to be as generic as possible in order to serve as many audiences as possible. Another is the possibility to distribute features to a closed group of sites.
Discussion: Features' futures
There are a lot of expectations on Features and Feature servers in the community. If you extend these ideas you can picture a future where modules on drupal.org are used strictly as general, flexible building blocks, and modules that are more related to specific use cases or problem domains move to a Features based distributed model, with a network of feature servers maintained by many different people and organizations.
Please share your thoughts in the comments!