Workflow
Magnolia CMS ships with a basic "four-eye" editorial content workflow. Authors and editors come across this pre-defined workflow for the first time when they activate content. Activations are submitted to a workflow queue for approval. A publisher can examine the workflow item, see what the changes are, who made them and when, and decide whether to publish the modified content to a public instance.
- Engine
- Workflow definition
- Accessing dialog fields
- Creating your own fields
- Participants
- Workitems in inbox
- Secure activation of content to a public instance
- Integration with external processes
The key point about the default workflow is that authoring and editorial review happen on the author instance. Content is published to public instance only when the workflow is completed.

Engine
Magnolia CMS uses the cross-platform OpenWFE workflow engine (manual). OpenWFE allows extensive workflow customization, making it possible to integrate Magnolia CMS into your legacy business processes. You can define your own activation and publishing workflows with as many stages and participants as needed.
The engine supports:
- Linear modeling and approvals.
- Branching and merging.
- Conditionals such as IF and multi-choice.
- Auto-escalation.
- Email notifications.
- Pre-defined workflows.
Workflow definition
Workflows are defined in XML. You can use a third party editor with syntax highlighting to enhance the editing experience. Generally we assume that workflows are defined by suitably skilled people. OpenWFE provides a flexible set of rules to accommodate business requirements and the XML markup is clean. Example:
<process-definition name="activation" revision="j0.0.2"> <sequence> <set field="activator" field-value="userName"/> <!-- Go to publisher first --> <to-publisher/> <!-- Will loop if rejected --> <if test="${field:action} == reject"> <revision-round/> </if> <log message="activate: ${field:action}"/> <!-- If the last action was proceed then activate--> <if test="${field:action} == proceed"> <activate/> </if> </sequence>
Workflow definitions are added and edited in AdminCentral in Configuration > Workflows. The system stores them in /modules/workflow/config/flows/.
Accessing dialog fields
Workflow definitions have access to the workflow dialog's fields. Timed activation of content is an example of this. When you launch a workflow you can indicate optional publication and expiration dates.

The dates are stored in the workitem in content nodes named after the startDate and endDate fields in the startActivationWorfklow dialog.

The activation workflow can read the dates using the ${f:<field name>} syntax and activate and deactivate content accordingly. The letter f stands for field. ${field:<field name>} works too.
<process-definition name="activate"> <sequence> <!-- Wait if scheduled --> <if> <defined field-value="startDate"/> <sleep until="${f:startDate}"/> </if> <!-- Deactivate if scheduled --> <if> <defined field-value="endDate"/> <sequence> <sleep until="${f:endDate}"/> <participant ref="command-deactivate"/> </sequence> </if>
In addition to startDate and endDate, the following properties are available. comment is the only field displayed in the dialog, the rest are just properties passed to the workflow definition.
actionperformed by the user such as "activate", "proceed", "reject"...activator. In the sampleactivationworkflow we setactivatorvalue to the user who launched the workflow. If a publisher rejects the change, we assign the workitem back to theactivator.usernameof the current user who lauched the workflow.repositoryor workspace where the activated content item resides such aswebsite.pathto the activated content item such as/demo-project/about/history.mailTemplateused for a workflow notification. Mail templates are configured in/modules/mail/config/templatesConfiguration.mailto. Recipient(s) of email notification. This can be a group such as group-publishers. Group members whose email address is registered in their user profile will receive the notification.commententered into the Comment field in the activation dialog.
- Create a simple workflow definition named
test. Log the property values using:
<log level="warn" engine-log="yes" message="<field name>: ${f:<field name>}"/>
<process-definition name="test" revision="0.0.1"> <sequence> <log level="warn" engine-log="yes" message="Comment: ${f:comment}"/> <log level="warn" engine-log="yes" message="Pub. date: ${f:startDate}"/> <log level="warn" engine-log="yes" message="Exp. date: ${f:endDate}"/> <log level="warn" engine-log="yes" message="Path: ${f:path}"/> <participant ref="group-publishers" /> </sequence> </process-definition>
2. Modify the activate command so it launches your test workflow instead of the default activation workflow. The workflow name is defined in /modules/adminInterface/commands/website/activate/startFlow/workflowName.

3. Activate some website content.

4. Observe the log file in apache-tomcat/logs/catalina.out:
WARN: Comment: Please review and publish. WARN: Pub. date: 2010-09-01 00:00:00+0200 WARN: Exp. date: 2010-09-30 23:59:59+0200 WARN: Path: /demo-project/news-and-events
Creating your own fields
You can create your own dialog fields and read their value from the workitem the same way. This allows you to define custom fields such as "Legal review required" that routes a workitem to the legal department or "Publish immediately" that bypasses the review process.
Here's an example of a dropdown list (select control) with three options. The dropdown is defined in the startActivationWorkflow dialog in /modules/workflow/dialogs.

The dialog will display the new field when content is activated. Users can select who should review the content.

The workflow definition routes the workitem to the responsible group based on the selected field value.
<process-definition name="test" revision="0.0.1"> <sequence> <case> <!-- Send to Marketing team --> <equals field-value="groupReview" other-value="group-marketing"/> <participant ref="group-marketing"/> <!-- Send to Legal team --> <equals field-value="groupReview" other-value="group-legal"/> <participant ref="group-legal"/> <!-- Send to Operations team --> <equals field-value="groupReview" other-value="group-operations"/> <participant ref="group-operations"/> </case> </sequence> </process-definition>
Participants
A participant is a reference to a user or program that takes part in the workflow. Participants are identified in the workflow definition by their name. OpenWFE understands four kinds of participants:
user-<user name>group-<group name>role-<role name>command-<command name>
<participant ref="user-john" />
Workitems in inbox
Workflow tasks are called workitems. They arrive at a workflow participant’s Magnolia CMS inbox.
A participant acts on the workitem by completing the required task such as reviewing a page change.
Permissions to view workflow items are controlled through Magnolia CMS user rights management. This allows an administrator or workflow supervisor to see workitems assigned to other users. Their inbox effectively functions as a "dashboard", displaying the status of the workflow process.
Since commands and processes can participate in a workflow, you can send email notifications on pending workitems. A workflow command can be attached to any event such as move page, activate, rename etc.
See Add custom column to inbox on how to customize the inbox.
Secure activation of content to a public instance
For security reasons, having only one user account on public instances is preferable. From a system perspective, where workflow is in the place, the only account necessary in order to activate content is the superuser. See also Activation and Security defaults.
Integration with external processes
While typical workflow participants are users, also scripts and commands can participate. This opens up the possibility to execute jobs and launch external processes at a given workflow stage. Conversely, an external process can participate in a Magnolia CMS workflow through a command or script.
Each module can provide its own commands. Commands are configured in /modules/<module name>/commands/<catalog name>/<command name>. A command is associated with a Java class through the class property.

For example, you could write a command that encapsulates the decision who (or which group or role) should receive the workitem next. The name of the "real participant" could be placed in a workitem field such as receiver.
<sequence> <participant ref="command-determinereceiver" /> <participant field-ref="receiver" /> </sequence>
command-<catalog_name>-<command_name>, for example ref="command-contenttranslationsupport-exportContent".