Drupal “Features” Module Introduction

The Features module is a popular module for Drupal 6 and Drupal 7. What does the features module do? The Features module was originally designed for a programmer to create a Feature or piece of a website that is reusable. An example of this may be a multi-user blog section of a website: its content type, permissions, url paths … all the configuration needed for a cookie-cutter blog area of a website could be a “Feature” of a website. To facilitate this idea the Kit Specification was created a long time ago.

I don’t often see Features used in this way. Typically, now-a-days Features is used to encapsulate Configuration and provide a mechanism to move code from 1 server to another — it’s a sane way to distribute your code between servers.

In Drupal 8 this configuration encapsulation has largely been implemented as the Configuration Management Initiative (CMI). In Drupal 8 it should be much easier to move pieces of Drupal configuration between development, testing and production servers as an example.

What is a Feature Then?

A “Feature” is just a Drupal Module. A Feature contains additional .info file directives that inform the Features module of what configuration Features’ is responsible for. An example Features .info file entries are:

name = Site Foundation
description = The foundation configuration settings (roles, permissions, logic) for my site.
core = 7.x
package = Foundation
php = 5.2.4
version = 7.x-1.7
dependencies[] = admin
dependencies[] = boxes
dependencies[] = ckeditor
dependencies[] = contact
dependencies[] = devel
dependencies[] = features
dependencies[] = menu
dependencies[] = relation
dependencies[] = strongarm
features[box][] = site_panel_001
features[box][] = site_panel_002
features[box][] = site_panel_004
features[box][] = site_panel_resources
features[ckeditor_profile][] = Full
features[ctools][] = boxes:box:1
features[ctools][] = strongarm:strongarm:1
features[features_api][] = api:1
features[field][] = node-page-body
features[filter][] = filtered_html
features[filter][] = full_html
features[menu_custom][] = main-menu
features[menu_links][] = main-menu:contact
features[menu_links][] = main-menu:instructor/reports
features[menu_links][] = main-menu:student/my-surveys
features[menu_links][] = main-menu:user/logout
features[node][] = page
features[user_permission][] = access administration pages
features[user_permission][] = access content
features[user_permission][] = access site in maintenance mode
features[user_permission][] = access site reports
features[user_permission][] = access site-wide contact form
features[user_permission][] = create relations
features[user_permission][] = use admin toolbar
features[user_permission][] = use text format filtered_html
features[user_permission][] = use text format full_html
features[user_permission][] = view own unpublished content
features[user_permission][] = view the administration theme
features[user_role][] = staff
features[user_role][] = student
features[variable][] = color_mytheme_palette
features[variable][] = comment_anonymous_page
features[variable][] = comment_default_mode_page
features[variable][] = comment_default_per_page_page

In the above info file you see the features keyword and it controls (exported) values for various site items such as Permissions, Roles, the contrib module Boxes, Input Filters, a CKEditor profile. Features typically references the machine_name of an item.

When you make a Feature through the Admin UI or using Drush it creates a module which in the .module contains at least 1 line of code at the top of the file:

   include_once(‘mymodule.features.inc’);

This allows Features to divine its responsibilities in your custom module. Additionally features may make additional *.features.inc files in your modules directory. If you export Field Configuration for example you will see mymodule.features.field.inc. If you export User Roles you will also see a mymodule.user_role.inc file. If a 3rd party module supports Feature’s Exportabability its features inc file is typically mymodule.features.CONTRIB_MODULE_NAME.inc.

These include files typically contain drupal, or contrib module Hooks that allow Features to create, alter and/or define an item of configuration.

An example exported Field from a mymodule.field.inc can be seen here:

/**
 * Implements hook_field_default_fields().
 */
function dew_foundation_field_default_fields() {
  $fields = array();

  // Exported field: 'node-page-body'.
  $fields['node-page-body'] = array(
    'field_config' => array(
      'active' => '1',
      'cardinality' => '1',
      'deleted' => '0',
      'entity_types' => array(
        0 => 'node',
      ),
      'field_name' => 'body',
      'foreign keys' => array(
        'format' => array(
          'columns' => array(
            'format' => 'format',
          ),
          'table' => 'filter_format',
        ),
      ),
      'indexes' => array(
        'format' => array(
          0 => 'format',
        ),
      ),
      'locked' => '0',
      'module' => 'text',
      'settings' => array(),
      'translatable' => '1',
      'type' => 'text_with_summary',
    ),
    'field_instance' => array(
      'bundle' => 'page',
      'default_value' => NULL,
      'deleted' => '0',
      'description' => '',
      'display' => array(
        'default' => array(
          'label' => 'hidden',
          'module' => 'text',
          'settings' => array(),
          'type' => 'text_default',
          'weight' => 0,
        ),
        'teaser' => array(
          'label' => 'hidden',
          'module' => 'text',
          'settings' => array(
            'trim_length' => 600,
          ),
          'type' => 'text_summary_or_trimmed',
          'weight' => 0,
        ),
      ),
      'entity_type' => 'node',
      'field_name' => 'body',
      'label' => 'Body',
      'required' => FALSE,
      'settings' => array(
        'display_summary' => TRUE,
        'text_processing' => 1,
        'user_register_form' => FALSE,
      ),
      'widget' => array(
        'module' => 'text',
        'settings' => array(
          'rows' => 20,
          'summary_rows' => 5,
        ),
        'type' => 'text_textarea_with_summary',
        'weight' => -4,
      ),
    ),
  );

  // Translatables
  // Included for use with string extractors like potx.
  t('Body');

  return $fields;
}

This is a Features hook to build fields — it’s basically defining array’s used in Drupal core to re-create your Field with field_create_field() and field_create_instance() with any and all configured FieldUI values for that field — and where in your drupal website it’s used (what Content Types or Entities).

The Features module itself provides an API with its own set of Hooks to alter, define and edit a Feature during its lifecycle. See the API.txt that ships with Features.

Using Features:

Typically you use the Features UI in the Drupal Administration area to export your feature. Or you may use Drush. Once you have a folder of files (your module) — you may move it between systems.

Features look at the .info file contents to derive what to do. If you add an entry that says Features controls some Field — you can use Drush and the command features-update to have Features export the related configuration to a Feature’s file code.

If you have a Feature and you’ve modified the configuration from within the Drupal Admin area — you may revert a Feature to the module’s defined configuration with features-revert.

A concise list of Drush Features options can be found in the help documentation:

$drush help --filter=features

All commands in features: (features)

features-add (fa)     Add a component to a feature module. (DEPRECATED: use features-export)     

features-components   List features components.                                                  
(fc)                                                                                             

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)

Hopefully this overview blog entry on Features helps you to make better use of Features on your site. A good rule of thumb when using Features is a Feature should do 1 thing — not many things.

Looking for quality Drupal Web Hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , , , , , | Posted under Drupal, Drush | RSS 2.0

Author Spotlight

David Gurba

David Gurba

I am a web programmer currently employed at UCSB. I have been developing web applications professionally for 8+ years now. For the last 5 years I’ve been actively developing websites primarily in PHP using Drupal. I have experience using LAMP and developing data driven websites for clients in aviation, higher education and e-commerce. If you’d like to contact me I can be reached at david.gurba@arvixe.com

Leave a Reply

Your email address will not be published. Required fields are marked *


8 × = 24

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>