Commit 4fabc6d6 authored by Charlie Clark's avatar Charlie Clark

STX help files moved to `docs` folder and converted to ReST

parent 2df697dd
Action Boxes
============
Action box settings are required for work lists and any transition that is
intended to be a user initiated action. They define how the action will
appear in the action box, what section it will appear in and what it will
link to.
Names and URLs for the actions box can be formatted using standard Python
string formatting. An example::
%(content_url)s/content_submit_form
The string '%(content_url)s' will be replaced by the value of content_url.
The following names are available:
* portal_url
* folder_url
* content_url
* count (Available in work lists only. Represents the number of items in the
work list.)
The following names are also available, in case there is any use for them.
They are not strings.
* portal
* folder
* content
* isAnonymous
Note that this formatting is done using standard Python string formatting
rather than TALES. It might be more appropriate to use TALES instead. As
always, patches welcome.
Expressions
===========
Expressions in DCWorkflow are TALES expressions. They are used as access
guards and for the setting variable values.
[**Note:** I haven't figured out what all these contexts actually are
and what you can use them for. Explanations are is welcome!]
Some of the contexts have slightly different meanings from what is provided
for expressions in page templates:
* 'here' -- The content object (rather than the workflow object)
* 'container' -- The content object's container
Several other contexts are also provided:
* 'state_change' -- A special object containing information about the state
change (see below)
* 'transition' -- The transition object being executed
* 'status' -- The former status 'workflow' -- The workflow definition object
* 'scripts' -- The scripts in the workflow definition object
'state_change' objects provide the following attributes, some of which
are duplicates of the above information:
* 'status' is a mapping containing the workflow status. This includes all the
variables defined in the variable tab with "store in state" checked.
* 'object' is the object being modified by workflow.(Same as the 'here'
variable above.)
* 'workflow' is the workflow definition object. (Same as the 'workflow'
variable above.)
*- 'transition' is the transition object being executed. (Same as the
'transition' variable above.)
* 'old_state' is the former state object. The name of the former state, for
example "published", is available as 'old_state.getId()'. (Note that
DCWorkflow defines 'state' and 'status' as different entities; the name of
the current 'state' is stored in the 'status'. The word clash is unfortunate;
patches welcome.)
* 'new_state' is the destination state object. Use 'new_state.getId()' to
access the new state name.
* 'kwargs' is the keyword arguments passed to the doActionFor() method.
* 'getHistory()', a method that returns a copy of the object's workflow
history.
* 'getPortal()', which returns the root of the portal.
* 'ObjectDeleted' and 'ObjectMoved', exceptions that can be raised by scripts
to indicate to the workflow that an object has been moved or deleted.
* 'getDateTime' is a method that returns the DateTime of the transition.
Guards
======
Guard settings control access to the transitions, variables or work lists.
Guards can be applied based on permissions, roles, groups or a TALES
expression. These elements are applied sequentially if they contain values.
If one of the conditions in each of the specified permissions, roles or
groups is met the guard element will be satisfied. For the guard to allow
access, all specified element that contain values must be satisfied.
If no permissions, roles or expressions are specified, access is
automatically granted.
You can supply several options in each field by separating them with a
semicolon.
The context in which the guards evaluate permissions and roles is obviously
important. In the case of transitions and work lists, it depends on the
category. If it's 'worklist', then the context is that of the content object,
and local roles will behave just as you'd expect. If the category is
'global', then the context will be the site root, so the local roles between
the site root and the content won't be considered.
[**Note:** What about variables?]
Overview
========
DCWorkflows provide workflow objects that are fully customizable via the Zope
Management Interface. You can specify the states, and the permissions they
set on content that is in that state, the transitions between those states,
and other things like variables for things that aren't well represented by
states, work lists for reviewers, and scripts to embody complex guards and to
extend pre and post transition behaviour.
The process for creating a workflow runs something
like this:
* Draw a state diagram with the nodes (bubbles) as states and the arcs
(arrows) as transitions. Remember to consider all the states your content can
be in, and for each state, consider who should have permission to access and
change the content. Consider what actions the users will perform to make the
transitions between states, and not only who will be allowed to perform them,
but who will be *required* to perform them.
It's often a good idea to start on paper, then transfer
the diagram to a digital copy using a diagram/flowchart tool, such as
'dia', so that you have an image to go with later documentation. This
process tends to make it easier to spot corner cases before you
actually create the workflow object.
* Start by creating an example DCworkflow, rather than a new one, as it's
faster to delete all the states and transitions than it is to create all the
standard variables that tend to be used by the CMF. [**Note:** Perhaps we
should have a bare dcworkflow, a workflow with standard variables, and the
couple of standard examples.]
* In the permissions tab, select all the permissions that you want the
workflow to govern. These will be dependent on the types of content you'll be
using with the workflow; 'Access contents information', 'Modify portal
content', and 'View' are the standard permissions for the default portal
content types.
* Define any extra variables that you need for information that isn't well
represented by states. [**Note:** generic examples? I can think of a few that
could appear in some use cases, but they're all idiosyncratic of particular
publishing needs]
* Set up the states for your workflow, one for each node in your state
diagram. Try to stick to the standard names for a publication workflow, as
some badly behaved products have states like 'published' hardcoded into their
searches (ie CalendarTool, last I looked) [**Note**: Maybe I should just file
some bug reports rather than casting aspersions :-)]. Set up the permissions
on the states now, as well, though see the "State Tab" section for advice.
* Set up any scripts that you will be using in your transitions, such as pre
and post transition scripts and to handle complex guard conditions. Just set
up skeletons for now, if you haven't though through all the details.
* Create your transitions from all the arcs on your state diagram. You
should be able to pick the right destination state as all your states
are already defined, and set up the right scripts to run, as you've
defined those as well. It's worth noting that the guard behaviour is
such that if any guard matches, the transition can occur. You can
specify more than one permission, role or expression by separating
them with a semicolon.
* Go back to the states tab and, for each state, set the possible transitions
from the list of all available transitions in each state.
* Finally, in the work lists tab, create any work lists for any states that
need them. Work lists are actions that indicate how many objects of a given
state are present, and usually link to some search page that lists the actual
object instances. You typically use them to list all the pending content
waiting for review. Work lists have several unusual behaviours, however, so
check the specific notes in the "Worklists" section.
By working in this order, you will tend to step through the
creation process one tab at a time, rather than switching back and
forth between them, which tends to be slower and somewhat confusing.
Permissions Tab
You can manage all of the actions a user can perform on an object by
setting up permissions to be managed by the workflow under the
permissions tab. Here, you can select which permissions should be
state-dependent from a list of all available permissions, and you
can delete previously selected permissions. In each state, use
it's permissions tab to set up the role to permission mappings
appropriate for that state.
Scripts Tab
===========
Scripts are used to extend the workflow in various ways. Scripts can be
External Methods, Python Scripts, DTML methods, or any other callable Zope
object. They are accessible by name in expressions, eg::
scripts/myScript
or::
python:scripts.myScript(arg1, arg2...)
From transitions, as before and after scripts, they are invoked with a
'state_change' object as the first argument; see the Expressions section for
more details on the 'state_change' object.
Objects under the scripts are managed in the usual ZMI fashion.
States Tab
==========
From the states tab it's possible to add new states, and rename and delete
existing states. It is also possible to set a particular state to be the
initial state that new content is set to when created.
The list of existing states also displays each state's title and all the
possible transitions from that state (and their titles). You can go straight
to the details of each state and transition from here.
Within a state's properties tab you can set the title, description, and the
transitions that are possible from this state from a list of all the
available transitions created in the workflow's transitions tab.
In the state's permissions tab, you can set up the roles to permissions
mappings that will apply to roles when content managed by this workflow is in
this state. It uses the usual cookie cutter approach as do all other
permissions tabs, except that the only permissions listed are those that have
been selected to be managed by the workflow from the workflow's permissions
tab.
A good strategy for managing permissions on each state is to rely on
acquisition for the "published" states, and to drop acquisition and use
explicit permissions on states that are private or interim publishing states.
This way, you can modify the access policy to "published" content at the site
root or for specific folders without having to modify each workflow's set of
"published" states.
[**Note**: The available roles in the permissions tab will be whatever is
acquired from the site root, so I guess creating roles under sub-folders
ought to be discouraged if people want to use them in workflows]
Reviewer roles should either have view permissions on every state or you
should change the appropriate skins to take them somewhere sensible after a
transition or they'll end up with an ugly access denied page after sending
content back to private state.
In the state's variables tab, you can add, change and delete variables that
you want to assign a value to when objects move into this state. The
available variables are set in the workflow's variables tab, and the value is
a TALES expression (see Expressions for more details).
Transitions Tab
===============
Transitions are the actions that move content from one state in the workflow
to another. From the transitions tab it's possible to add new transitions,
and rename and delete existing transitions.
The list of existing transitions also displays a summary of each transition's
title, description, destination state, trigger, guards, and action box entry.
You can click through each transition to access their details.
Within a transition's properties tab you can set the title, and a collection
of properties the define the transtion's behaviour, as follows:
**Destination state** --
selected from all the states defined in the states tab. A transition can
remain in state, which is useful for a reviewer adding comments to the review
history, but not taking any action, updating some variable, or invoking
scripts.
**Trigger type** --
There are two types:
* User actions are the familiar user initiated transitions activated by
actions in the action box.
* Automatic transitions are executed any time other workflow events occur;
so if a user action results in the content moving to a state that has
automatic transitions, they will be executed. (You should use mutually
exclusive guards to prevent indeterminate behavior.)
**Scripts** --
Perform complicated behaviours either before or after the transition takes
place. Scripts of all kinds are defined in the workflow's scripts tab.
Scripts called from here must accept only one argument; a 'status_change'
object. See Expressions for more details.
**Guards and Action boxes** --
See the :doc:`Gaurds` and :doc:`ActionBoxes` sections for specific details
about those fields. Note that automatic transitions don't need the action box
fields to be filled out.
What the action should link to.
In the transition's variables tab, you can add, change and delete variables
that you want to assign a value to, when the transition is executed. The
available variables are set in the workflow's variables tab, and the value is
a TALES expression (see Expressions for more details).
Variables Tab
=============
Variables are used to handle the state of various workflow related
information that doesn't justify a state of it's own. The default CMF
workflows use variables to track status history comments, and store the the
last transition, who initiated it and when, for example. From the variables
tab it's possible to add new variables, and rename and delete existing
variables.
The list of existing variables also displays a summary of each variable's
description, catalog availability, workflow status, default value or
expression and any access guards. You can click through to each variable to
configure it's details.
In each variable's property tab you can set the variable's description and a
collection of properties the define the variable's behaviour, as follows:
**Make available to catalog** --
Just as it says, it makes this variable available to the catalog for
indexing, however it doesn't automatically create an index for it - you have
to create one by hand that reflects the content of the variable. Once
indexed, you can query the catalog for content that has a particular value in
is variable, and update the variable by workflow actions.
**Store in workflow status** --
The workflow status is a mapping that exists in the state_change object that
is passed to scripts and available to expressions.
**Variable update mode** --
Select whether the variable is updated on every transition (in which case,
you should set a default expression), or whether it should only update if a
transition or state sets a value.
**Default value** --
Set the default value to some string.
**Default expression** --
This is a TALES expression (as described in Expressions) and overrides the
default value.
**Guards** --
See the :doc:`Guards`.
**State variable** --
stores the name of the variable the current state of the content is stored
in. CMF uses 'review_state' by default, and will have already created a
FieldIndex for it. The state variable is effectively a variable with "Make
available to catalog" set, a default value of whatever the initial state is
and a default expression that sets to the new state on every transition.
Worklists Tab
=============
Work lists are a way to make people aware of tasks they are required to
perform, usually reviewing content in the publishing context. Work lists are
implemented as a catalog query that puts an action in the actions box when
there are some tasks the member needs to perform.
From the work lists tab it's possible to add new work lists, and rename and
delete existing work lists. The list of existing work lists also displays a
short summary of each work list's description, the catalog query it uses, and
any guard conditions. You can access the details of each work list by
clicking on them.
In each work list's properties tab, you can set the description of the work
list, and it's various behaviour defining properties. The "Catalog variable
matches" field sets the state that is work list matches. The "variable_name =
" text to the left of the text box is the name of the state variable defined
at the bottom of the variables tab. The values can be set to a number of
possible matches separated by semicolons. [**Note:** CVS feature. There's
more in doc/worklists.stx, but I'm not sure I understand the implications]
The action box fields are discussed in more detail in the Action Box section.
In this case, the url that the work list links to should probably implement a
search page with a catalog query similar to the "Catalog variable matches",
otherwise the difference between the number of items waiting and the items
reported in the search will be confusing.
[**Note:** What we *really* need from the work list is a way to define full
catalog queries for the action, and a new action box variable that urlquotes
that query so it can be passed straight to the search page. This way, the
work list count and the number of items on the search page will be the same
as they are derived from the same query string, defined in one place.
Reply from Shane: work lists already exercise the catalog too heavily, and
most people don't understand their purpose. Expanding their capabilities
further could impact performance. I think perhaps the UI should instead
display work lists on a user's home page rather than the actions box, which
would open up new possibilities.]
The guard fields are described in detail in the :doc:`Guards` section. It's
probably better to avoid using permission and role guards, as they're not
really necessary - a user will see a work list action only if they can see
content in that particular state, so the state guards are usually sufficient.
In addition, as the work lists are in the 'global' actions category by
default, and global actions are evaluated in the context of the site root,
local roles like Owner or locally set Reviewer roles, and the permissions
they grant, will not apply. [*Note:* Does anyone know a good reason why work
lists appear in the global box rather than in the workflow box? This
particular problem should vanish if they are moved there.]
Whether a work list action appears in the action box, and the number of items
in the work list depends on several factors:
* The state that the work list is generated for
* The name of the state variable used to indicate the current state of an
object
* Whether the user can view content which is in that state
This has some unexpected consequences:
* If you have several workflow that use the same state variable, and similar
state names, and each has a work list on, say, the 'pending' state, then both
work lists will appear in the action box, and the number of items in each
will be the total of all the content in a 'pending' state, regardless of
which workflow manages that content (except that if the work list action
entries are exactly the same text, the action tool will filter out the
duplicate).
* If each workflow manages the permissions on content in the 'pending' state
differently, by, say, using two different reviewer roles, then users who have
one role and not the other will see a single work list entry with the right
number of items, but users with both roles will see the same as above.
So there are a few tricks to getting the work lists to do the kinds of things
we want.
If you have several similar workflows, such as a standard one, and a couple
of specialized ones for particular content, and you want to have one reviewer
role for the lot, then you should set up just one work list in the standard
workflow for the states that need them, and leave the other workflow to rely
on that work list.
If you have a workflow that uses a different reviewer role than other
workflows, and consequently, you want it to have it's own separate work
lists, you have two choices. One is to use state names that are unique to
each workflow, while the second is to use state variable name that is unique
each workflow. The second option is obviously a lot easier, however, if you
change the name of the state variable when there exists content that is using
this workflow, they will immediately loose there workflow state and default
to the initial state. In addition, you'll need to add a field index for the
new state variable name in the portal_catalog tool, by hand.
[Note: In the first instance, we could add an action box name field to each
state so that nicely formated names appear in the action box for things like
"Published (yet to be effective)" rather than "published_not_yet_effective",
and so we can lie about the names to make them unique, so that
"foo_workflow_pending" looks like "Pending". In the second instance, I see no
reason why the state variable name change action shouldn't migrate the value
of the old state variable to the new for all the content managed by this
workflow, and it could probably automatically add indexes for new state
variable names if they don't already exists (and perhaps remove indexes for
state variable names not used elsewhere).
While we're thinking about ways to make sweeping workflow changes less
painful, there are a couple of changes that could be made to the code that
changes content type to workflow mappings: if a content to workflow mapping
has changed, then, for each instance of that content type, attempt to keep
the state variable the same unless that state doesn't exist in the new
workflow, then evaluate any automatic transitions on that state. This way
it's possible to migrate between workflows by ensuring that states with the
same name have the same semantics, or if they don't exists in the new
workflow, we can create placeholder states with an automatic transition to
the state we want to be in.]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment