Complex websites and web applications can be created by combining
configurations of Modules, Fields, Content Types, Menus, Blocks,
Categories, Roles / Permissions, etc… This site setup and
configuration process is a very time consuming and repetitive
bottleneck.
The Patterns module is built to bypass this bottleneck by managing and
automating site configuration. Site configuration is stored in YAML, XML, or
PHP files called Patterns. These files have a structure which is
easy to read, modify, manage, & share and can be executed manually or as
a part of an automated web site deployment.
Patterns is installed as a Drupal module. Its dependencies are the Token and Libraries modules.
It makes uses of external libraries which must be installed separately:
Spyc and Codemirror.
-
Spyc is a native PHP library used to parse YAML files. It is
necessary for the correct functioning of Patterns.
-
Codemirror is a Javascript library which
considerably enhances the interface of the Patterns editor page. It
is not necessary for the correct functioning of Patterns, but
recommended.
Both libraries should be installed under sites/all/libraries/
under directory names of spyc and codemirror2.
A Pattern is a file composed by an info section (generic metadata about the pattern)
and a sequence of _action_s of the type create, modify, or delete grouped in
categories (sections). The tag: expression tells Patterns which component to use.
Every component defines a list of tags it can handle, see later. After choosing the tag,
the pattern file has to supply every required data for the particular action.
In this example: name, machine_name, description, hierarchy are some of the data keys used, and all of them have values assigned.
The data is passed to the pattern component as an associative array, most often referred to as $data.
Some actions have alternative or optional parameter requirements.
Categories can be arbitrarily defined (excluding the
reserved words) and are executed sequentially.
# This is a comment
# Example Pattern
info: # mandatory name
title: New Vocabulary
description: Adds a new vocabulary to the website
author: QScience
category: Examples
version: 1.0
core: 7.x
author_email: sbalietti@ethz.ch
author_website: http://qlectives.eu
actions: # any name is good for this category
- create:
tag: vocabulary
name: Another Vocabulary
machine_name: anothervoc
description: Another interesting vocabulary
hierarchy: 0
- modify:
tag: vocabulary
machine_name: anothervoc
description: It was not that interesting after all
# vid: 2
- delete:
tag: vocabulary
machine_name: anothervoc
# vid: 2
Two other optional sections names are modules and include.
modules explicitly defines a list of modules to enable during the execution of the
pattern, while include loads the actions of another
pattern into the current one. More explanation later TODO
3.1. Reserved Words
Pattern works by parsing the pattern file and then constructing a form
which contains the values for specific elements. The form is
then validated and submitted, just as if the submit button had been pressed from
a browser window.
The processing can be done in two ways. The Batch mode uses Drupal’s Batch API
to run the patterns in the background. This helps overcome the time limitations
and the user gets feedback of the progress. The other method, which is called PHP,
executes the tasks in a single PHP run. In this case, debugging can be easier.
In order to have your custom module be able to benefit from patterns,
you must create a component, much like a driver software. The main components
reside in patterns/components/, although modules can use the hook_patterns_components hook
to expand the set of supported components.
You need to implement at most 7 pattern hooks, as here explained in the same
order as they are being called by Patterns module. For examples, see the block.inc, system.inc, taxonomy.inc.
where $action is one of the actions create, modify,
delete and $tag is the specific command to execute
(e.g. vocabulary, field, etc.).
hook_patterns is called independently from the others hooks, which
are invoked sequentially to perform an action. In particular, if
calling hook_patterns_prepare and hook_patterns_validate does not raise error,
moreover hook_patterns_prepare returns some form ID’s, the engine do the following
for each form ID:
-
execute hook_patterns_build, and hook_patterns_params while checking for errors;
-
submit the form (call the Drupal function drupal_form_submit);
-
execute hook_patterns_cleanup while checking for errors.
5.1. Return values
5.1.1. hook_patterns()
Returns the following array of actions:
$actions['tag1'] = array(
PATTERNS_INFO => t('Description of this tag'),
PATTERNS_CREATE => array('form_to_create_tag1', 'form_to_create_tag2'),
PATTERNS_MODIFY => array('form_to_modify_tag1', 'form_to_modify_tag2'),
PATTERNS_DELETE => array('form_to_delete_tag1', 'form_to_delete_tag2'),
PATTERNS_FILES => $files = array('some file that needs to be included'),
);
$actions['tag2'] = ... ;
where $tag1, $tag2 etc. are specific commands to execute
(e.g. vocabulary, field, etc.). The list of possible form ID’s is also provided
for each of the three actions (create, modify, delete). Note that this array
can be empty as well, see function hook_patterns_callbacks.
5.1.2. hook_patterns_build, hook_patterns_params, hook_patterns_cleanup
All the other hooks return the following special associative array:
-
status: One of [PATTERNS_SUCCESS, PATTERNS_WARN, PATTERNS_ERR]. Required.
-
msg: A message.
-
result: Any kind of additional data.
Patterns execution can follow two distinct behaviors:
-
Extend: adds the settings defined in the pattern file into the
current instance, and leave untouched what not explicitly
specified.
-
Run-Over: re-configures the whole web site in order to create an
instance with exactly the settings defined by the pattern, and
removes everything not explicitly specified.
6.1. Differences between Extend and Run-Over
The action create changes according to the behavior selected for the
execution.
-
create:
-
extends : always create a new entity;
-
run-over: always check if the target entity is existing, if not, create it.;
-
modify: check if the target entity exists and then modify
it. Does nothing if the entity is not found;
-
delete: check if the target entity exists and then delete
it. Does nothing if the entity is not found.
6.1.1. Entity Matching
Entities are matched on the base of their id, if provided, or more
commonly on their machine name.
-
PHP file names: any extra php used for Patterns execution should begin
with the prefix patterns.. E.g.: patterns.editor.inc;
-
Function names: functions declared in .inc files should contain
the name of the .inc file in their
name. E.g. patterns_io_save_pattern() is defined in
includes/patterns.io.inc. Notice: does not apply for theme functions.
-
AJAX call: methods which are called during AJAX operations, and
print directly their output instead of returning it should end with
the suffix _service. E.g. : patterns_parser_validate_service();