Last updated September 9, 2013. Created by fago on August 16, 2010.
Edited by jenlampton, mitchell, August1914. Log in to edit this page.

Providing default rules may serve as a simple way for modules to provide some default functionality, which users may override. Also it's useful for versioning rule configurations in code using the usual version control system or to build feature-like modules.

Modules may provide default rules using hook_default_rules_configuration(). For optimizing the memory footprint,
you may put the hook implementation in the include MODULE.rules_defaults.inc - which is automatically picked up. Be sure to prefix the default rules with your module name to avoid name collisions.

Consider the example taken from the testing module:

<?php
/**
* Implements hook_default_rules_configuration().
*/
function rules_test_default_rules_configuration() {
 
$rule = rules_reaction_rule();
 
$rule->label = 'example default rule';
 
$rule->active = FALSE;
 
$rule->event('node_update')
       ->
condition(rules_condition('data_is', array('data:select' => 'node:status', 'value' => TRUE))->negate())
       ->
condition('data_is', array('data:select' => 'node:type', 'value' => 'page'))
       ->
action('drupal_message', array('message' => 'A node has been updated.'));
 
$configs['rules_test_default_1'] = $rule;
  return
$configs;
}
?>

As seen, the hook has to return an array of rule configurations keyed by configuration name. This technique allows that any type of configuration may be provided, including components.
Configurations in code may be overridden by the user, whereas those overrides are stored in the database. To avoid that you may set $rule_config->status = ENTITY_FIXED;. Read more about exportable entities (=> rule configurations) here.

Managing your exported rules in code

You can also export every rule individually into it's own file and check these in to git. (This makes changes to individual rules easier to see and manage). The files can be placed into a /rules/ folder inside your custom module, and each one can end in a .rule extension.

Then, you can place a single function inside the file mymodule.rules_defaults.inc in mymodule. In that function you can loop through all the files, and import each rule.

Here's an example of the mymodule.rules_defaults.inc file:

<?php
/**
* Implements hook_default_rules_configuration().
*/
function mymodule_default_rules_configuration() {
 
$config = array();
 
$rules_path = drupal_get_path('module', 'mymodule') . '/rules';
 
$files = file_scan_directory($rules_path, '/\.rule$/');
  foreach (
$files as $filepath => $file) {
    require
$filepath;
    if (isset(
$rule)) {
     
$config['mymodule_' . $file->name] = rules_import($rule);
    }
  }
  return
$config;
}
?>

And here's an example of a something_or_other.rule file (don't forget the opening php tag!):

<?php
/**
* Rule exported to code: auto_alias_product_type.
*/
$rule =
 
'{ "auto_alias_product_type" : {
      "LABEL" : "Auto alias for new product type",
      "PLUGIN" : "reaction rule",
      "REQUIRES" : [ "rules", "path", "entity" ],
      "ON" : [ "commerce_product_insert" ],
      "DO" : [
        { "path_alias" : {
            "source" : "classes\/[commerce-product:product-id]",
            "alias" : "classes\/[commerce-product:title]"
          }
        }
      ]
    }
  }'
;
?>

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

You can use rules_import() to create the $rule from any exported code you have.

    $rule = rules_import($data);
    $configs[$rule->name] = $rule;

Thanks tcmug.

Here is an example code. http://drupalcode.org/project/commerce_stock.git/blob_plain/eddda60f384d...

/**
* @file
* Default rule configurations for Commerce Stock.
*/
function commerce_stock_default_rules_configuration() {
  $rules_decrement_stock_completing_order = '{ "rules_decrement_stock_completing_order" : {
      "LABEL" : "Decrease stock when completing the order process",
      "PLUGIN" : "reaction rule",
      "REQUIRES" : [ "commerce_stock", "commerce_checkout" ],
      "ON" : [ "commerce_checkout_complete" ],
      "DO" : [
        { "LOOP" : {
            "USING" : { "list" : [ "commerce_order:commerce-line-items" ] },
            "DO" : [
              { "commerce_stock_decrease_by_line_item" : { "commerce_line_item" : [ "list-item" ] } }
            ]
          }
        }
      ]
    }
  }';
  $configs['rules_decrement_stock_completing_order'] = rules_import($rules_decrement_stock_completing_order);
  return $configs;
}

Cheers,
TechNikh

Ever dreamed of styling your view, We have a solution for you. https://drupal.org/project/views_stylizer
Pick from hundreds of Slideshow plugins or create your own! https://twitter.com/drupalsauce

I handle my rule exports very similar to this comment on the Drupal 6 documentation. I'll add some code examples to the docs page above. Hope this helps someone until ctools exports are integrated :)

When writing hook_default_rules_configuration() it took me a while to find out how to define a parameter as a 'data selection' value not a plain text value. You need ':select' in the array key after your parameter name. Otherwise the value is treated as pain text. Here is my code from the Scheduler module:

<?php
$rule
->action('scheduler_set_publish_date_action',
              array(
'node:select' => 'scheduler-node', 'date:select' => 'scheduler-publish-on-date'));
             
// The keys required above are 'node' and 'date', which are the names defined in scheduler_rules_action_info()
              // followed by :select to specify data selection instead of plain text values.
?>

This was not immediately obvious in the documentation I had read, but I found it by reading examples of others, and trying it out.

Jonathan