1. Rules Mastery training
This document contains notes and information for the training Rules Mastery given at
DrupalCon Denver, March 19th 2012. This document can be found at http://tinyurl.com/
rulesmastery.
General information
Training resources
General resources for Rules
Schedule
About the exercises and training pace
Part 1: Rules configuration
1a: Reaction rules, ‘set a data value’ and ‘data selection’
1b: Creating and calling components
1c: Adding the level-up functionality
1d: Looking at some more actions
1e: Working with fields
1f: Lists and loops
1g: Views Bulk Operations and Rules components
1h: Rules Scheduler
1i: Extra stuff
Part 2: Coding for Rules
2a: Adding new data to the ‘site’ pseudo entity
2b: Writing conditions
2c: Writing actions
2d: Writing events
2e: Extra stuff
General information
This Rules training is conducted by Johan Falk (Itangalo) with great help from Wolfgang
Ziegler (fago), Dick Olsson (dixon_) and Klaus Purer (klausi). The training consists of short
demonstrations of concepts, followed by own work with exercises. Exercises, and their
suggested solutions, are available as screencasts.
Training resources
● All screencasts for this training
2. ● Custom features and modules for this training: sandbox project | zip download
● Devel Rules: sandbox project | zip download (Note: This module accidentally invokes a
hook that causes some problems. Only use this module when you really need it.)
● File archive for this training
● General training information from DrupalCon organizers (regularly updated)
General resources for learning Rules
● The Rules project page
● Rules online documentation
● Rules developer documentation
● The Rules discussion group
● Screencasts “Learn the Rules framework”
● Screencasts “Coding for Rules 2”
● The Tiny Book of Rules (source)
Schedule
7 am Registration opens!
8 am Continental breakfast (with tea!)
9–10 am Introduction, getting to know Rules
10–10:30 am Break
10:30–12 More complex Rules configuration
12–1 pm Lunch, outside classrooms
1–2:30 pm Getting into coding for Rules
2:30–3 pm Break
3–4:30 pm More Rules coding
4:30–6 pm Looking at the things we didn’t have time to cover, or just doing
whatever we want with Rules
About the exercises and training pace
When doing training with more than one person, it is inevitable that some people finishes
exercises before others. If you’re quick with an exercise – I recommend the following:
1. Tweet “Ready for more!” or something like that with the tag #rulesmastery. This will help
us instructors to see when the class as a whole is ready to move on.
2. Experiment with Rules and try things that look interesting. Don’t hesitate to ask if you got
questions!
3. 3. Check out another exercise – there are usually at least two exercises for each topic, and
there are also some bonus material and two Master Exercises to chew on.
Part 1: Rules configuration
During the morning we will be working with site functionality that reminds of the User Points
module, awarding users with “Drupal points” for different things they do. The site we will be
working with is a fictive documentation site – a feature with the base setup is available for
download.
● Make sure you have the required sandbox modules downloaded: Rules Mastery (zip)
and Devel Rules (zip).
● Make sure you have the required contrib projects downloaded: Rules, Entity API,
Features, Strongarm, Chaos tools suite (ctools), EVA: Entity Views Attachment,
Entity reference, Flag, Views, Views Bulk Operations, plus – also recommended for
convenience – Administration menu and Module Filter.
○ Drush command to get them all: drush dl rules entity features strongarm
ctools eva-1.1 entityreference flag views views_bulk_operations admin_menu
module_filter
○ Zip with the contrib modules: download
● Enable module/feature with start setup for the site, “Rules Mastery start setup”.
● Get an overview of the functionality in the start setup: demo
1a: Reaction rules, ‘set a data value’ and ‘data selection’
In the first exercise we will look at reaction rules, reacting when certain events occur on the site.
We will especially be using the ‘set a data value’ action, using the ‘data selection’ function in
Rules, and also look at some basic conditions.
● Create a reaction rule that gives new accounts 5 Drupal points: task | solution
● Create a reaction rules that awards 10 Drupal points for creating a new topic and 20
points for new tutorials: task | solution
1b: Creating and calling components
In the second exercise we will work with components – stand-alone Rules configuration that
may (for example) be called as actions. Components are especially useful if you find yourself
repeating the same configuration.
We will especially be looking at component ‘parameters’ – their input data.
The result of this exercise is available as the feature “award Drupal points
component”. But there’s a bug in it – to make it work, add ‘.inc’ to the file name of
rulesmastery_award_drupal_points_component.rules_defaults.
● Create a component that awards a selected user a specified number of Drupal points:
task | solution
○ Also make this component output the new point status for the user as a
message. (“User [NAME] now has X points.”)
4. ● Bonus task 1: Display a different message if the points are awarded to the acting user.
(“You now have X points.”)
● Bonus task 2: Display a different message is points are subtracted rather than added.
1c: Adding the level-up functionality
Gathering Drupal points may be fun in itself, but it is even more fun if they allow you to level up.
This level-up functionality is Rules-based (including some code), but the configuration is pretty
darn complex. You can find it as a Master Exercise at the end of this chapter, if you want to
have a closer look at how it is built.
● Enable the feature “level up functionality”
● Have a look at the new cool functions on the site: demo
1d: Looking at some more actions
Before moving along, we might want to spend some time looking at the available actions and
conditions in Rules. These exercises are not super-complex, but good for getting more familiar
with Rules.
● Investigate the existing Rules components, and update the relevant one to (a) show
a message when a user levels up and (b) also send an e-mail to that user: task | (no
suggested solution)
● When someone likes a piece of content, award the author of that content 2 Drupal
points: task | solution
○ Also make sure that the two points are retracted if the liking is removed.
○ Bonus task 1: Don’t award points when liking your own content.
○ Bonus task 2: Check out the tips on how to debug Rules configuration, at the end
of the exercise list – this shows how to award points to the liking user as well.
1e: Working with fields
Rules can read and write all fields in core, and quite a few of the fields provided by contrib
modules. In these exercises you will see how fields can be used both as simple and complex
data.
It is important to remember that if there are more than one bundle of an entity, you must use the
“entity has field”/”content is of type” condition for the fields to be accessible to Rules.
● When someone creates an easy tutorial, award them 10 extra Drupal points: task
| solution
● When someone creates a tutorial, award 3 points to (the author of) the referenced topic:
task | solution
● Good bonus task: Add the ‘difficulty’ field to topics as well, and when someone creates a
tutorial belonging to a difficult topic – award them 5 extra points. (No screencasts, sorry.)
1f: Lists and loops
5. The concept of lists is a new, powerful and really cool part of Rules. Lists may correspond to
multiple-value fields – being lists of whatever data type the field holds – but can also be just
general lists of data. Rules has some actions and conditions that work with lists by themselves,
but it is also possible to loop through a list to perform actions on each element in the list. (See it
as a for each-loop.)
● When a comment is deleted, award 1 point to any user reporting the comment as spam:
task | solution
○ Bonus task: Unpublish a comment when the third spam flag is set.
● When a piece of content is promoted to the front page, all the users commenting on that
content should be awarded 1 point for each comment they made on that content: task |
solution
1g: Views Bulk Operations and Rules components
The Views Bulk Operations module (VBO) is an awesome tool for creating administration
pages, and it works really well together with Rules. In these exercises you should get some
experience in using Rules components as actions in VBO.
● Either enable the feature “base for VBO”, or build your own view: example
● Create a component that allows resetting the Drupal points for an account using VBO:
task | solution
● Allow awarding an arbitrary number of Drupal points to accounts, using VBO: task |
solution
1h: Rules Scheduler
Rules Scheduler can take Rules components, populate any required parameters, and schedule
the execution of the component to a later point in time. In these exercises you will also see that
this can be used to create recurring actions.
● When a user has been a member on the site for one week, she should get 50 Drupal
points as a one-time boost: task | solution
● After the initial boost, members should get 10 points every week: task | solution
○ Bonus task: Remove the weekly bonus when the user reaches level 4.
○ Extra bonus task: If a user doesn’t log in for three months, his/her Drupal points
should be reset. (Ouch!) However, after two months, an email should be sent to
the user to warn of this unfortunate event.
1i: Extra stuff
This extra material may be useful when you have gotten more comfortable using Rules.
● Master exercise 1: When people have written content that is promoted to the front
page, they should 1 Drupal point for every piece of content. This should be awarded
once every day that the content remains on the front page: task | solution | corrections
● Master exercise 2: Try to understand how the level-up configuration is put together (or
rebuild it yourself): task | solution
6. ○ Super master exercise bonus deluxe: Modify the level-up functionality so it
removes roles when a user loses points enough to pass a level limit.
● Bonus material: tips on how to debug Rules configuration
Part 2: Coding for Rules
During the afternoon we will be building a module that allows us to block comments containing
selected words. We build this module in a generalized way, allowing Rules to read a list of
words maintained by site administrators – and use this list of words for both conditions and
actions.
● Enable the Rules coding module. (You probably also want to open it in your code editor.)
● Have a look at the functionality that the module provides: demo
● Have a look at the Devel Rules module: demo
2a: Adding new data to the ‘site’ pseudo entity
First thing we want to do with this module is to allow Rules to read the list of words that we can
set. There are several ways of doing this, but a simple one is to make it available in the ‘site’
pseudo entity: task | solution | code | zip
● Use Devel Rules to check out the properties of the ‘site’ pseudo entity.
● Check out how the list of words is stored (by reading the module code).
● Find a suitable data type for the word list.
● Implement hook_entity_property_info_alter() to add a new property to the site pseudo
entity, representing the list of words.
● Write a function representing the ‘getter callback’ for the new property.
○ Bonus exercise: Implement a ‘setter callback’ to make allow Rules to write – not
only read – the word list.
2b: Writing conditions
If we want to use the list of words to block comments containing any of the words, we will need
a new condition. This condition should take a list of words and a long text, and tell us whether
any of the listed words appear in the text: task | solution | code | zip
● Use Devel Rules to check out some existing conditions.
● In rulescoding.rules.inc, implement hook_rules_condition_info() to declare a new
condition to Rules. Take extra care to describe the parameters for the condition.
● Write the function that should evaluate the condition.
● Don’t forget to clear the cache.
○ Bonus exercise: Add a setting for case sensitive/insensitive comparison: task |
solution | code | zip
2c: Writing actions
7. To practice writing actions, we will write an action that allows replacing any occurrences of given
words in a text, for example changing any blacklisted words to ‘BLEEP’.
Writing actions is very similar to writing conditions, but one important difference is that actions
may provide new variables back to Rules: task | solution | code | zip
● Use Devel Rules to have a look at some existing actions.
● In rulescoding.rules.inc, implement hook_rules_action_info() to declare a new action.
Take extra care to describe both the parameter and provides parts.
● Write the function that performs the action. Take extra care to return the ‘provides’
variable in the proper way.
● Don’t forget to clear the cache.
2d: Writing events
Finally, we should also look at how to provide new events to Rules. We do this by adding an
event representing that the global list of words is being saved, and this event should tell Rules
both how the old and the new list of words looks.
Events are written in two steps – first part is to declare the event to Rules, and the next is to
actually invoke the event somewhere: task
● Use Devel Rules to have a look at some existing events.
● In rulescoding.rules.inc, implement hook_rules_event_info() to declare the new event.
Take extra care to describe the variables correctly: solution pt 1 | code pt 1
● In the function saving the list of words, invoke the new event using rules_invoke_event().
Make sure to pass along the required variables: solution pt 2 | code pt 2 | zip
2e: Extra stuff
Writing conditions, actions and events is just the start of coding for Rules – but a very useful
start. Here are some tips on more things you can learn in the area of Rules coding.
● Passing event variables by reference: In the event exercise, Rules isn’t able to
change the content of the newly saved list of words. There are ways to make this
possible: demo | code | zip
○ Super ultra bonus exercise: Find what’s wrong with the suggested solution
above.
● Exotic settings for parameters/variables: It is possible to change a lot of the standard
behaviour of variables used by conditions and actions – for example forcing manual
input (disallowing data selection), providing select lists for input, and more. The
documentation of hook_rules_action_info() in rules.api.php describes this quite well.
● Creating data types: Sometimes you need to add new data types to Rules, when
your data structures don’t match the existing data types. This is done in a way
quite similar to how we modified the ‘site’ pseudo entity. An example is found in
rulesmastery_start_setup.rules.inc.
● Calling rule components from code: If you are writing a module that includes
configurable conditions, you could rely on Rules components instead of writing your own
condition engine. Components are called with the rules_invoke_component() function,