Kicking the tires of Drupal's Features module
As noted in a previous blog entry, Quick look at the Package Builder module for Drupal, and prepackaged functionality, I'm associated with a gang of people thinking about creating a packaged Drupal distribution. In the previous blog entry I looked at Package Builder, and in this one I'm looking at the Features module. They provide similar featuritis but it is possibly true that Features has bigger mindshare in the Drupal community than Package Builder does. Something that has stood out however is a group of recent podcasts on the Lullabot site that make Features sound like it is the wave of the future.
These are: Drupal Voices 117: Earl Miles on Views 3, Panels and CTools, Drupal Voices 116: Sam Boyer on the Panels module, Drupal Voices 115: Young Hahn on Features and the future of Context ... and while Podcast 84: All About Buzzr isn't about Features it is interesting listening anyway
For the purpose of an exercise to see how well (or if) Features works, I'm working on building a set of features that would together make a web directory. What I mean is something akin to the open directory project or for the old timers in the room, Yahoo's original website which was largely a directory of web sites. That is, a list of links to web sites organized in a hierarchical taxonomy, good navigation of the taxonomy, and for each taxonomy term a list of related terms and a list of links (nodes) that have that taxonomy term.
I've implemented something like this in other web sites. Further on a couple websites I have significant collections of links and would rather start a separate site to house those links than keep them where they are. Maybe. Oh, and it would be interesting to automagically create a descriptor file for the Google Custom Search Engine service.
At the moment I've implemented a "link" node type and a view that is a beginning stab at the per-term display page. I've created three versions of this feature and attached them to this post. The "link" node type is very simple, just uses the "link" and "location" CCK fields. The view is a simple listing of nodes which has an "Term ID" argument. Nothing terribly complex.
The Drupal.org handbook on Features is rather helpful but there is some missing bits here and there.
The first step is to create the content type and the view. Have at it, if you're thinking about using features you're probably advanced enough to know how to create a content type and a view. Have fun.
Once the content type and view is created go to Admin / Site Building / Features. It has a vertical tab arrangement that lists some subsectioning of features; on my site one tab was labeled "Amazon" and another "testing". It makes sense why there's a "testing" tab as it's labeled as being tests for the features module, but I don't grok how "Amazon" got there. Anyway to create a feature you click on the "Create feature" link.
Unfortunately the UI for creating the feature is a little confusing. There's a video linked from the Features module project page that helped me get over the initial hump. The idea is that Features lets one select aspects of the system that make up the feature. It packages those aspects as a module. The module can then be installed on other systems, and there is also some magic allowing the feature to be stored on a feature server and I believe updated via the update mechanism. I haven't checked that part out but it does sound rather magical.
The Features module relies on the CTools module to provide an "Exportables" concept which is what can take some bit of Drupal configuration and turn it into code. The code is then shareable as a module. At this point I want to refer the reader back to a rant I posted in the prior blog post. Is a feature best represented as a module? I really don't know but it does seem to me that modules and features are somewhat distinct things, however they do have some measure of overlap.
Getting back to selecting aspects of your system. In the Create Feature page there are some boxes where you enter the feature name, the version, and so on. That's straightforward. Down at the bottom of the page is where the confusing UI lives. There is a dropdown list that lets you select various kinds of aspects to export. As you select different kinds of aspects, specific examples of those aspects show up below as checkboxes. Clicking on a checkbox discovers the specific things required, and adds them to a list. Once you've selected everything you click on the "Download Feature" button and you're given a File Save dialog at which point your feature module thingymajig ends up on your computer.
Basically - that UI is confusing. Once you get it, well, it's a bit less than confusing.
The dropdown is marked "Add components". Why, I don't know, but that's what the label reads. On my Drupal install the entries in this list are "Content", "Permissions", "Views", and "Dependencies". Selecting "Content" lists the content types configured in the system, selecting "Permissions" lists the various permissions from that admin screen, selecting "Views" lists the enabled views, and selecting "Dependencies" lists the module names.
Once the feature module is created copy it to a different drupal installation. They suggest installing it in sites/all/modules/custom/features but don't explain why that's a preferred location. They do say the feature module can be installed "anywhere" but still imply the modules/custom/features is a better location, without saying why. In any case you don't enable the feature module using the Modules admin page, but instead by using the Features module page. Once the feature module is unpacked it shows up on the Features admin page and can be enabled there. However it also shows up on the Modules admin page.
All that's fairly well despite the rough edges pointed out above. But, wait, there are even more rough edges.
It doesn't export the workflow setting named "Promoted to front page". I exported the module, imported it on the other site, and the content type didn't have the "Promoted to front page" box unchecked. I'm guessing that because the CTools Exportables concept is not "in core" that there is some kind of boundary condition where it cannot export core stuff. The "Promoted to front page" setting is a core Drupal setting and not a setting from a contrib module. Regardless of the explanation it is downright inconvenient. The Features module UI implies that it is exporting a content type definition and by golly it ought to export all aspects of the content type definition.
It doesn't even offer to export Vocabulary definitions. I defined a "Link Tags" vocabulary to go with the Link content type, and configured that Link Tags vocabulary in the view. But it didn't show a "Vocabulary" component nor offer me any way to select that vocabulary as a thing to include in the feature module. Further the vocabulary did not get into the feature module and was not created on the other site. Urgle, this vocabulary is a core aspect of the feature I'm developing and it's downright inconvenient that it's not exporting the vocabulary. Repeat my guess work from the previous paragraph about Features not being capable of exporting core things.
Because I created three subsequent versions of the feature I did get to experience the feature upgrade process. Rather, the lack of a feature upgrade process. I'd have thought there would be a way to upload the new feature or otherwise drop it in the file tree and run an update process. That's how you handle updating regular modules, so why not handle updating feature modules the same way? The first time through I simply unpacked the .tgz file for the feature on top of the existing module, but that didn't seem to do any update. So I disabled the feature, then re-enabled it. It does know that when disabling a feature that leaves some modules unused, it might be a good idea to uninstall the "orphaned" modules. That's rather reassuring, really.
I also learned that if the admin were to modify some settings in something installed by a feature - say, modifying a view installed by a feature - that the modified setting is detected and marked as "Overidden". This addresses a major concern from my previous blog post - how do you deliver a feature to a customer and accommodate the customer modifying some aspect of the feature such as a view definition. Features detects the modification and handles it appropriately.
I'm struggling to understand what seems to be a major missing feature in Features. That is, when you create a feature it doesn't remember that you created the feature. That means when you create version 1.1 of the feature you have to completely recreate the feature from scratch. It doesn't remember version 1.0 of the feature and allow you to use that as a starting point for version 1.1 of the feature. Darned inconvenient if you ask me.
If you've installed a feature on a site you can use the Update link to go to a page which looks amazingly like the Create Feature page, but has the existing state of the feature already filled in, and then you get to change things and export a new version of the module. It would seem this is the methodology to satisfy the issue in the previous paragraph. And maybe I'm not groking the expected work flow. But ... uh...
It provides some drush commands
features List all the available features for your site.
features-export Export a feature from your site into a module.
features-revert Revert a feature module on your site.
features-update Update a feature module on your site.
The first is a simple list of the features
[ps21776]$ drush features
Name Feature Status State
Amazon Examples amazon_examples Disabled
Features Tests features_test Disabled
Link CCK link_cck Enabled
The features-export command, well, I don't grok what it wanted to do. I ran it and got this message which leads me to believe it would have overwritten the already installed feature module. Uh, say what?
Module appears to already exist in sites/all/modules/
Do you really want to continue? (y/n): n
Uh.. the README has this to say:
drush features-export [context]
This command lets you create a new feature in code from one or more
context definitions. It will write a new feature module with a name
matching the ->value portion of the context definition.
Which, uh, ah, what's a 'context'? Since I don't know what they mean by context this doesn't do any good. It's obvious that they meant a different thing by "export" than what I expected. And reading further I see the "features-update" option is what I wanted. You just have to be willing to engrave the feature module into the files sitting in your file system.
[ps21776]$ drush features-update link_cck
Module appears to already exist in sites/all/modules/custom/features/link_cck
Do you really want to continue? (y/n): n
It's an interesting module that desperately needs some UI work to make it understandable.