--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/development/datamodel/define-workflows.rst Thu May 07 16:33:22 2009 +0200
@@ -0,0 +1,159 @@
+.. -*- coding: utf-8 -*-
+
+.. _Workflow:
+
+An Example: Workflow definition
+===============================
+
+General
+-------
+
+A workflow describes how certain entities have to evolve between
+different states. Hence we have a set of states, and a "transition graph",
+i.e. a list of possible transitions from one state to another state.
+
+We will define a simple workflow for a blog, with only the following
+two states: `submitted` and `published`. So first, we create a simple
+`CubicWeb` in ten minutes (see :ref:`BlogTenMinutes`).
+
+Set-up a workflow
+-----------------
+
+We want to create a workflow to control the quality of the BlogEntry
+submitted on your application. When a BlogEntry is created by a user
+its state should be `submitted`. To be visible to all, it has to
+be in the state `published`. To move it from `submitted` to `published`,
+we need a transition that we can call `approve_blogentry`.
+
+A BlogEntry state should not be modifiable by every user.
+So we have to define a group of users, `moderators`, and
+this group will have appropriate permissions to publish a BlogEntry.
+
+There are two ways to create a workflow: from the user interface,
+or by defining it in ``migration/postcreate.py``.
+This script is executed each time a new ``cubicweb-ctl db-init`` is done.
+We strongly recommand to create the workflow in ``migration/postcreate.py``
+and we will now show you how. Read `Under the hood`_ to understand why.
+
+Update the schema
+~~~~~~~~~~~~~~~~~
+If we want a State for our BlogEntry, we have to define a relation
+``in_state`` in the schema of BlogEntry. So we add
+the line ``in_state (...)``::
+
+ class BlogEntry(EntityType):
+ title = String(maxsize=100, required=True)
+ publish_date = Date(default='TODAY')
+ text_format = String(meta=True, internationalizable=True, maxsize=50,
+ default='text/rest', constraints=[format_constraint])
+ text = String(fulltextindexed=True)
+ category = String(vocabulary=('important','business'))
+ entry_of = SubjectRelation('Blog', cardinality='?*')
+ in_state = SubjectRelation('State', cardinality='1*')
+
+As you updated the schema, you have to re-execute ``cubicweb-ctl db-init``
+to initialize the database and migrate your existing entities.
+
+[WRITE ABOUT MIGRATION]
+
+Create states, transitions and group permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``postcreate.py`` script is executed in a special environment, adding
+several `CubicWeb` primitives that can be used.
+They are all defined in the ``class ServerMigrationHelper``.
+We will only discuss the methods we use to create a workflow in this example.
+
+To define our workflow for BlogDemo, please add the following lines
+to ``migration/postcreate.py``::
+
+ _ = unicode
+
+ moderators = add_entity('CWGroup', name=u"moderators")
+
+This adds the `moderators` user group.
+
+::
+
+ submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
+ published = add_state(_('published'), 'BlogEntry')
+
+``add_state`` expects as first argument the name of the state you want
+to create, then the entity type on which the state can be applied,
+and an optional argument to say if it is supposed to be the initial state
+of the entity type.
+
+::
+
+ add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
+
+
+``add_transition`` expects
+
+ * as the first argument the name of the
+ transition, then the entity type on which the transition can be applied,
+ * then the list of states on which the transition can be trigged,
+ * the target state of the transition,
+ * and the permissions
+ (e.g. a list of user groups who can apply the transition; the user
+ has to belong to at least one of the listed group to perform the action).
+
+::
+
+ checkpoint()
+
+.. note::
+ Do not forget to add the `_()` in front of all states and transitions names while creating
+ a workflow so that they will be identified by the i18n catalog scripts.
+
+In addition to the user group condition, we could have added a RQL condition.
+In this case, the user can only perform the action if
+the two conditions are satisfied.
+
+If we use a RQL condition on a transition, we can use the following
+variables:
+
+* `%(eid)s`, object's eid
+* `%(ueid)s`, user executing the query eid
+* `%(seid)s`, the object's current state eid
+
+
+.. image:: images/lax-book.03-transitions-view.en.png
+
+You can notice that in the action box of a BlogEntry, the state
+is now listed as well as the possible transitions defined by the workflow.
+The transitions will only be displayed for users having the right permissions.
+In our example, the transition `approve_blogentry` will only be displayed
+for the users belonging to the group `moderators` or `managers`.
+
+
+Under the hood
+~~~~~~~~~~~~~~
+
+A workflow is a collection of entities of type ``State`` and of type ``Transition``
+which are standard `CubicWeb` entity types.
+For instance, the following lines::
+
+ submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
+ published = add_state(_('published'), 'BlogEntry')
+
+will create two entities of type ``State``, one with name 'submitted', and the other
+with name 'published'. Whereas::
+
+ add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
+
+will create an entity of type ``Transition`` with name 'approve_blogentry' which will
+be linked to the ``State`` entities created before.
+As a consequence, we could use the administration interface to do these operations.
+But it is not recommanded because it will be uselessly complicated
+and will be only local to your instance.
+
+
+Indeed, if you create the states and transitions through the user interface,
+next time you initialize the database
+you will have to re-create all the entities.
+The user interface should only be a reference for you to view the states
+and transitions, but is not the appropriate interface to define your
+application workflow.
+
+