As you build Drupal sites, define content types, setup Views and image presets, you end up making a lot of configuration changes. One of the problems with Drupal (up to and including Drupal 7) is that content and configuration is all stored in the database. I'm sure you have experienced the real headache when you want to move the content types, views and various configuration changes from a development site to production site or to another site entirely. You end up repeating configuration changes again (and again).
Wouldn't it be nice if you could package up all of that configuration into a module? It could then act like any other module - you put it on other websites and just enable it to get all of the functionally. Or build it on a dev machine, and easily move it to the live site. Enter the Features module.
The Features module
The Features module allows you to build "features" using site building, rather than writing the actual code yourself. Each feature is a set of components for a particular use case. For example, a blog feature. You create a blog content type, a view of blog posts, an image style for blog images etc. You then build a feature with those components. This is a module that you can turn on to give you functionality when you enable it.
“The features module enables the capture and management of features in Drupal. A feature is a collection of Drupal entities which taken together satisfy a certain use-case.” Extract from http://drupal.org/project/features
When you create a Feature, you are in fact creating a module. All the exported configuration is stored in files in the module’s directory. Just like any other module, it can be version controlled (using Git, Subversion or similar), deployed and shared.
In this tutorial, you are going to build a todo list, called Todotoday. You will start off by building the functionality without writing any code. You will then turn it into a module using Features. Our todo list will contain a set of tasks. A task is simply an item that needs to be done.
Add content type
The first thing you are going to do is to create a content type called Task. We will treat each task as a Drupal node. This will gives you tremendous flexibility if you want to extend the module, or allow other modules to interact with it.
Let’s get cracking and create the content type.
Click on Structure from the main menu and a dialog will appear. Click on Content type.
Figure 1: Structure menu
You will now see a list of current content types. Click on Add content type.
Figure 2: Content types
You will then be presented with a form to complete. You will want to call the content type Task so that when a user wants to add a new task, they will simply go to Add Content and Task. So go ahead and add Task to the name field.
Figure 3: Task content type
You will notice that the machine name is automatically filled in. A machine name is Drupal’s internal name for a content type.
Figure 4: Content type name
You want to change this and prefix it with our module name. This will help keep things organised in the database. When you have many content types, it is helpful to be able to identify which module they belong to. So let’s click edit and change the machine name to todotoday_task.
Figure 5: Edit human-readable and machine name
Next, you need to add a description. This will be displayed when a user adds a new task, so you can say something like “Task to add to todolist”. You also should change the title from “Title” to “Task”. This makes it clear to the user to add their task in the title field.
Figure 6: Description
On the left hand side of the bottom half of the form, you will see a bunch of tabs. These contain various default options for the content type. Click on Publishing options. New content types are set to Published and Promoted to front page. However, as you do not want our Todo list Tasks to end up on the front page, un-tick this option.
Figure 7: Default publishing options
Figure 8: New publishing options
You could just save the content type now. But you need to add some fields, so click on Save and add fields.
Add Status Field
You are going to add a status field. So in Add new field, add the following:
Label: Status Machine name: field_status Field: List (text) Widget: Select list
Figure 9: Add new field
After you click save, you will get a form with Field settings. Here you need to add the options for our select list. Add New, Started and Done.
Figure 10: Field settings
You will then see a bigger form with more settings. Here you want to change the default value for Status to New.
Figure 11: Default value
Add due date field To add a date field, you need the Date module. Download it from the Date module project page. You need to enable both the Date and Date Popup module, which is supplied with the Date module download. Enable them in the modules page (admin/modules).
Add the date field. Set the following: Label: Due date Field: Date Widget: Pop-up calendar
Figure 12: New date field
On the Field Settings screen, set the date attributes to Year, Month and Day only.
Figure 13: Field settings screen
Now, let’s try adding an item. Go to Content, Add Content and Task. You will be presented with our shiny new interface for adding Tasks.
Figure 14: Create task
The only problem is, you have a massive body field. This is a simple todo module, so you probably don’t need the body field. Let’s go back to edit the content type and get rid of it. Go back to the content type, edit it and edit fields. You will see the body field along with the Status, Due date and Title fields.
Figure 15: Body field
Click delete next to Body and confirm.
Now, click on Add Content and Task again. Now you have a nice simple form with Task, Status and Due date fields.
Figure 16: Add task with new fields
Let's put in some dummy tasks such as buy some milk, wash the car, walk the dog.
Figure 17: New task
Set Buy some Milk to Done, Wash the Car to Started and leave Walk the Dog as New.
Add to feature
If you go to the content list (Content -> Find Content), you will see the Tasks you just added. So far so good. Now you need to turn all this configuration into a Features module.
The first thing we need to do is to add the Feature module. Download it from the Features project page. Enable Features in the modules page (admin/modules).
Now that Features is installed, let’s use the interface to create our Todotoday feature module. Go to Structure and then Features.
Figure 18: Structure screen
The top part of the form is the basic information about the feature. Fill it in like so:
Figure 19: Features form top
The bottom part of the form is where you add the components of the feature. So far, you just have a content type. Clicking on the Edit components drop down reveals the available components. Select Content types: node and then select Task. Your form should now look like this:
Figure 20: Features form bottom
As you can see, the status field that you added has been pulled into the feature automatically.
Now you can download the feature and save it. A module that you create using Features is a lot like a custom module. This is especially true if you eventually add custom code to the module. So I prefer to save Features along side any custom modules that I create in sites/all/modules/custom. Drupal does not come with a custom directory, so if you haven't created one already, create one now.
Some people prefer to create a directory just for the Features they create instead of putting them in the custom modules directory. You can read more about this and other ways to structure your modules directory in how to structure your modules directory.
After you have added the downloaded Feature to sites/all/modules/custom and go back to Structure -> Features (admin/structure/features), will see Todotoday listed. That is the feature module you just created!
Figure 21: Manage Features screen
You will notice that it is not enabled yet. You can enable it by ticking the box and saving. Because this is actually a module, you can enable it on from the modules page (admin/modules) as well.
Now that you have a nicely packaged and contained Feature module, you can copy it to another site and simply enable it to get all of the functionality it contains. If you use source control (Git, Subversion etc), you can add this module just like you would any other module. If you have a dev and production site, you can easily move this module and any changes to it from dev to production without having to repeat any configuration changes.
In this tutorial, you started to create a simple todo list in the Drupal UI. You then used the Features module to export the configuration to an actual module without writing a single line of code. You can of course create Content Types and Views without exporting to a module using Features. But there are big advantages in doing this. Now that all the configuration is in code, it can be treated like any other module. It can be put under source control (such as Subversion or Git) and deployed easily.
In the next tutorial, I will walk you through how to add a View to the feature by re-exporting it. If you are not on the mailing list, jump on to ensure you don't miss it!
If you would like to learn more about creating features modules and how to take them to the next level with custom code, grab a copy of Master Drupal Module Development.