Foswiki provides a flexible system of Access Control Lists that can be used to control who can modify a topic. Sometimes this isn't quite enough, and the access control depends on the state that a topic is in.

For example,
  • When writing documents compliant with ISO 9000 (e.g. a quality manual), it is essential that documents are approved by quality control
  • In a defect tracking data base, defects typically transition through a series of states, from submission to resolution, with different actions available depending on the state of the defect.
  • In a journal database, papers must be reviewed and approved by several experts in the field before being allowed to be published.

WorkflowPlugin lets you associate a state with a topic and then control what other states that the topic can move to. You can define a set of states for controlled topics (e.g. "under revision", "waiting for approval", "approved") and transitions (e.g. "revise", "approve") between these states. Furthermore, you can define which users/groups are permitted to perform specific transistions.

A workflow can be associated with a single topic, or with an entire web.

Upgrade note If you are upgrading from a version before 10 Nov 2008 please note that the format of the WORKFLOWHISTORYFORMAT preference has changed slightly, in that:
  1. enclosing double quotes are no longer removed from the value. This changes has been to bring this preference definition into line with other preference definitions.
  2. $n is interpreted as \n, not <br>, in line with the standard format tokens. If you want a <br> in the format string, then enter it as <br> or $percntBR$percnt.


A topic is under document control if the preference variable WORKFLOW is set in the topic page. WORKFLOW must be set to the wiki name of a topic that describes your specific workflow (the workflow description topic).

Note: you can hide the setting in a normal view using HTML comments, or better, you can put these settings into the local topic settings, accessible from the "more" screen.

Settings in the workflow description topic

The workflow description topic must contain one state table and one transition table. The state table describes the possible states a document may be in (nodes in the flow diagram above), and the transition table describes how documents move between states (arcs in the flow diagram).

This is easiest illustrated using an example (available as DocumentApprovalWorkflow if the plugin is installed).

The state table is a table with three columns:

| *State*       | *Allow Edit* | *Message* |
| UNDERREVISION | QualityGroup | This document is being revised. |
| APPROVED      | nobody       | This document has been approved for release. |
| WAITINGFORQM  | nobody       | This document is waiting for approval by the Quality Manager. |
| WAITINGFORCTO | nobody       | This document is waiting for approval by the CTO.|

Each row in the table defines a state where:
  • the State column specifies a name for the state,
  • the Allow Edit column specifies who is permitted to edit the topic when it is in the state, and
  • the Message column defines a message which can be displayed on the document page when the document is in this state.

In the example we have defined four states. Members of the QualityGroup are permitted modify documents can make changes to the document in UNDERREVISION state. In all other states, nobody is allowed to edit the controlled document.

The first state in the table is the initial/default state.

ALERT! The state table must be defined before the transition table!

The transition table consists of four columns, as in this example:
| *State*       | *Action* | *Next State*  | *Allowed*                        |
| APPROVED      | revise   | UNDERREVISION | QualityGroup                     |
| UNDERREVISION | complete | WAITINGFORQM  | QualityGroup                     |
| WAITINGFORQM  | approve  | WAITINGFORCTO | QualityManager                   |
| WAITINGFORQM  | reject   | UNDERREVISION | QualityManager,QualityGroup      |
| WAITINGFORCTO | approve  | APPROVED      | TechnicalDirector                |
| WAITINGFORCTO | reject   | UNDERREVISION | TechnicalDirector,QualityManager |

Each row in this table defines a transition from one state to another state:
  • the State column contains the name of a state from the state table,
  • the Action column describes a possible action when the topic is in this state,
  • the Next State column defines the new state of the document after the specified action has been performed,
  • the Allowed column specifies who is allowed to perform the corresponding action,
  • an optional Form column defines a form that is attached to the topic in this state.
  • an optional Notify column specifies who should be notified when this transition fires.

In our example, anyone is allowed to revise the document when it is in UNDERREVISION state. After finishing the revision, the document can be transitioned to the WAITINGFORQM state by any member of the QualityGroup. It must then be approved by the QualityManager, and after that by the TechnicalDirector. Even though they can't edit the document themselves (see state table above), they can reject the revision and put the document back into the UNDERREVISION state. The TechnicalDirector can transition the document to APPROVED state where it rests until a member of the QualityGroup puts it under revision again.

If a form name is given in the Form column, this form will be attached to the topic, and the topic will put in edit mode to allow information to be provided in the form when that state transition happens. In the example above, a form of type ApprovedForm will be attached to the topic when the CTO transitions the topic into APPROVED state.
  • if there is already a form of a different type attached to the topic, then any fields that have the same name in the new form will be preserved.
  • If no form is given, the existing form (if any) is left in place.
A typical usage of the form would be to collect additional information as the topic walks through the work flow, or to make information in the form unchangeable (by setting it to a label field) once a given state is reached.

If a Notify column is given, that column can contain a comma-separated list of notification targets to be informed when the transition is fired. You can specify values in any combination of the following formats:
Format Example Notes
Email addresses  
User wiki names WikiGuest  
Wiki group names AdminGroup  
Workflow Attribute names LASTUSER_APPROVED LASTUSER_{State}
Email templates template(Web.MyTopic) Must be wrapped in parentheses and proceeded by the word template, all lowercase, no spaces.

When a transition is fired, any email addresses provided in the Notify column (or resolved from wiki/group names) will be notified, with a message formatted according to the default email template provided with the plugin. You can override this template by setting the WORKFLOWDEFAULTEMAILTEMPLATE preference in your workflow description topic. Set that to a topic that contains a valid email notification template (see example below), and all email addresses provided will receive messages formatted according to that template:

Subject: %WIKITOOLNAME%.%WEB%.%TOPIC% - transitioned to %TARGET_STATE%
Auto-Submitted: auto-generated
MIME-Version: 1.0
Content-Type: text/plain

%WIKINAME% has moved the topic %WEB%.%TOPIC% to the %TARGET_STATE% state.  You can view the document here:

Email notification templates should be topics formatted like the example above, with the headers each on their own line, followed by a single colon, then their values, with the message body beginning below the first blank line. Also note the %EMAILTO% macro on the To: line; any email addresses pulled from the Notify column for a given transition will be expanded here. If you override the default email template using the WORKFLOWDEFAULTEMAILTEMPLATE preference, it must use the %EMAILTO% to pull in recipients, otherwise you'll need to provide your own macros, and any email addresses provided in the Notify column will be ignored. See the content-sensitive workflows section for more on how WorkflowPlugin expands macros.

For more sophisticated email notification, you can also write one or more custom email templates for each transition. Custom notification templates can either provide valid headers that define their recipients or access the EMAILTO macro, so other email addresses provided will be sent exclusively through custom templates.

For example, the Notify column in the transition below will email using the default template, and execute both the EmailOne and EmailTwo templates, sending the results to whatever email addresses are defined on their respective To, Cc, or Bcc lines:
| *State* | *Action* | *Next State* | *Allowed* |  *Notify*                                               |
| PENDING | approve  |   APPROVED   |           |, template(EmailOne), template(EmailTwo) |

Note: it's a good idea to avoid editing email notfication templates with a WYSIWYG editor, as they are somewhat fragile.

Settings in your controlled document/topic

As described above the topic needs to contain a definition for the variable WORKFLOW for it to be controlled under the approval workflow. This is best set as a document-specific preference setting in the More topic actions screen.

WORKFLOW* -- macros associated with WorkflowPlugin

All the following macros accept web and topic parameters:
Parameter Meaning Default
web (Optional) name of the web containing the topic current web
topic (Optional) name of the topic (may use web.topic syntax) current topic

Where it makes sense, the macros also accept a rev parameter.

If the topic is not controlled, then any references to WORKFLOW macros are simply removed. You can use this behaviour to place these tags in the header or footer in your skin templates. They appear only if the currently displayed topic is controlled.


Expands to a link that lets you attach to the topic (if you are not able to modify the topic, either in the workflow sense or according to the tandard access controls, the link will be struck out).


Expands to a link that lets you edit the topic (if you are not able to modify the topic, either in the workflow sense or according to the standard access controls, the link will be struck out).|


Expands to a button that will create one or more copies of a topic (which must be in a workflow). You must have edit (CHANGE) access to the topic to be forked.

Parameter Meaning Default
newnames="NameOne,NameTwo,..." Comma-separated list of name(s) of the new topic(s) to create. AUTOINC is supported, and you can use a web specifier on the topic names. required, no default.
label="Fork" Label to use in the button "Fork"
lockdown="on" Set this if you want the forked topic to be set as uneditable by all except admins after the fork. This will also prevent the topic from being forked again. off
Used when you have a topic that has to be split to follow different routes through a workflow - for example, when a requirement is refined to create two new requirements that must follow their own lifecycles; or perhaps a problem report is found to affect two different components of a system, and the resolutions have to be separately tracked.

For example, %WORKFLOWFORK{topic="OriginalTopic" label="Divide and conquer" newnames="ForkPathOne,ForkPathTwo" lockdown="on"}% will create two copies of OriginalTopic, named ForkPathOne and ForkPathTwo and set the OriginalTopic as uneditable (using ALLOWTOPICCHANGE).

The fork copies do not inherit the history of the forked topic - their history starts afresh with the fork.

ALERT! due to a bug in versions of the plugin prior to Oct 2009, the default parameter was interpreted as the name of the new topic to fork to. This has been corrected, but the macro will revert to the old meaning if you omit the newnames parameter.


Expands to either (a) a pull-down menu if the user can perform more than one transition, (b) a button if the current user can only perform one transition, or (c) empty space if the current user is not allowed to perform any action. You can change the format of the button using a CSS class (see WORKFLOWTRANSITIONCSSCLASS below) or by deriving your own version of workflowstrings.tmpl


Expands to the history of state transitions the topic has undergone.

Parameter Meaning Default
format Format of each transition $state -- $date
header Header before results  
footer Footer after results  
separator Separator between results <br />
include Perl regular expression matching states to include  
exclude Perl regular expression matching states to exclude  

The format, header, footer and separator parameters provide the control necessary to make the history look nice when it is viewed.

In this example the history is formatted as a simple table:
%WORKFLOWHISTORY{format="| $state | $author | $date |" separator="$n"}%

The standard format tokens are supported, as well as the following special tokens:
Token Expands to
$author Who triggered the transition to this state (also $user and $wikiusername)
$comment Comment accompanying the record
$date Date/time of the transition in the default format (you can format your own date using the same formatting tokens as used by %GMTIME%)
$index 1-based number of this result
$name Version at the transition (also $rev)
$state The state of the topic after the recorded event occurred


Expands to the history recorded when the topic was last in a certain state.

Parameter Meaning Default
"State" Name of the state  
format Format $rev: $state $author $date

The format is the same as that used for %WORKFLOWHISTORY%.


Expands to the current state of the topic.


Expands to the corresponding message in the state table for the current state.

If you replace %EDITTOPIC% with %WORKFLOWEDITTOPIC% in your skin templates, then the Edit link is crossed out when the user is not allowed to edit the page in a state.

Similarly, you can use %WORKFLOWATTACHTOPIC% in your skin templates to cross out the Attach link.

Content-sensitive workflows

Advanced Flows can be made sensitive to the content of the controlled topics. The 'Allow Edit' column in the state table, and the 'Next State' and 'Allowed' columns in the transition table, support the use of macros which are expanded when the topic is viewed. For example, you can use the META macro to pick up values for these fields from the form attached to the viewed topic:

State table
| *State*             | *Allow Edit*                         | *Message* |
| WAITINGFORAPPROVAL  | %META{"formfield" name="MayModify"}% | This document is waiting for approval |
Transition Table
| *State*            | *Action* | *Next State*                             | *Allowed*                        |
| WAITINGFORAPPROVAL | approve  | %META{"formfield" name="ApprovedState"}% | %META{"formfield" name="MayApprove"}% |

If you want to exclude the user who changed a specific state last, even though the user is generally allowed to, you can add not(LASTUSER_{State}) to the Allowed column of the transition table and the last user for the specified state will be excluded.

You can also define other macros starting with WORKFLOW in the workflow description topic. These will be expanded to their defined values in any topic that uses the workflow. For example:
  • Set WORKFLOWNOTICE = This topic is under document control.
will define WORKFLOWNOTICE in any topic that uses the workflow.


A common requirement is to report on the status of topics that are in different states in the workflow. You can use the query search to search for topics in a specific state. For example, to search for all topics in state "APPROVED":
%SEARCH{"'APPROVED'" type="query"}%

History and Acknowledgements

This plugin was motivated by Thomas Weigert's WorkFlowAddOn and its first version (then called ApprovalPlugin) was written by Thomas Hartkens, albeit it was focused on document approval and control. Thomas Weigert then merged the functionality of the WorkFlowAddOn into this plugin.

Installation Instructions

You do not need to install anything in the browser to use this extension. The following instructions are for the administrator who installs the extension on the server.

Open configure, and open the "Extensions" section. Use "Find More Extensions" to get a list of available extensions. Select "Install".

If you have any problems, or if the extension isn't available in configure, then you can still install manually from the command-line. See for more help.

Note: The script will convert topics written for the ApprovalPlugin to the WorkflowPlugin. The script takes a topic at the standard input and outputs the converted topic on standard output. Rename the file from to

Look at the examples in the Sandbox web.

Note: For strict access control, the plugin should know who is looking at the controlled document/topic at all times. To enable this, you may want to set up the wiki in such way that users have to log-in even if they just display a topic.
Topic revision: r8 - 01 Jun 2018, AdminUser
This site is powered by FoswikiCopyright &© by the contributing authors. All material on this site is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback