Workflow represents the lifecycle of a piece of content: in other words, the various stages or operations that can be carried out during its lifetime.

Below is a graphic representation of the workflow used by default in Ametys CMS :

Workflow steps and actions are described in a file XML. This workflow can be easily modified by editing the corresponding file.

Ametys is based on the OSWorkflow workflow engine

Application workflows

Automatically declared workflows (fromAmetys 4.2)

In version 4.2, the 4.1 procedure described below still works, but it is recommended that you proceed as follows:

If there is no WEB-INF/param/workflows file, xml is automatically generated with the contents of the WEB-INF/param/workflows folder. To add a workflow, simply place the file in this folder.

The file name (without extension) will become the workflow "name".
For the "content" workflow, you need a WEB-INF/param/workflows/content file. xml

Manually declared workflows

In the CMS application, the WEB-INF/param/workflows.xml file lists the application's various worfklows, with their names and locations:

<workflows>  
    <workflow name="content" type="file" location="workflow.xml"/>  
    <workflow name="newsletter" type="file" location="workflow-newsletter.xml"/>  
    <workflow name="blog" type="file" location="workflow-blog.xml"/>  
</workflows>  

The "name" attribute is used to name the workflow, while the "location" attribute indicates the location of the workflow description file.

The workflow named "content" is used by default for most content on CMS (articles, news, FAQ, ...).

Some content provided by other plugins sites may have different lifecycles and therefore define their own workflows. This is the case, for example, with plugin Newsletter for "Newsletter"-type content and plugin Blog, which provides a simplified workflow for "Post"-type content.

Naming life cycles 

For each workflow definition, you must define a key i18n WORKFLOW_workflow_name in the application catalog (WEB-INF/i18n /application_* .xml )

<message key="WORKFLOW_bpm-default">Processus avec double validation expert/élus</message> 

Workflow description file

A workflow is made up of states (step) and actions leading to these states (action).

There are 4 types of action:

  • les actions initiales : il s'agit des actions permettant d'initialiser le workflow (l'action de création par exemple). Elles sont décrites dans la balise <initial-actions>
  • les actions globales: il s'agit des actions pouvant être effectuées depuis n'importe quel état. Elles sont décrites dans la balise <global-actions>
  • les actions communes : il s'agit des actions pouvant être effectuées depuis plusieurs états différents. Elles sont décrites dans la balise <common-actions>
  • state-specific actions: these are actions that can only be performed from a particular state. They are described in the state itself

Tous les états sont décrits dans la balise <steps>.

Each action and state must have a unique numerical identifier and a name (key i18n).

Example of a workflow file

<workflow>  
 <initial-actions>  
 <!-- Création-->  
 <action id="0" name="plugin.web:WORKFLOW_ACTION_CREATE">  
             ...  
        </action>       
    </initial-actions>  

 <!-- Actions globales -->  
    <global-actions>  
 <!-- Suppression -->  
 <action id="5" name="plugin.web:WORKFLOW_ACTION_DELETE" finish="TRUE">  
             ...  
        </action>  
    </global-actions>  

 <!-- Actions communes -->  
    <common-actions>  
 <!-- Edition -->  
 <action id="2" name="plugin.web:WORKFLOW_ACTION_EDIT">  
             ...  
        </action>  
 <!-- Validation-->  
 <action id="4" name="plugin.web:WORKFLOW_ACTION_VALIDATE">  
             ...  
        </action>  
 </common-actions>  

 <steps>  
 <!-- Etat Brouillon -->  
 <step id="1" name="plugin.web:WORKFLOW_STATE_DRAFT">  
             <common-action id="2"/>  
  <common-action id="4"/>  
  <!-- Proposition -->  
  <action id="3" name="plugin.web:WORKFLOW_ACTION_PROPOSE">  
              ...  
           </action>  
 </step>  
 <!-- Etat Proposé-->  
 <step id="2" name="plugin.web:WORKFLOW_STATE_PROPOSED">  
            <actions>  
 <common-action id="2"/>  
 <common-action id="4"/>  
 </action>  
        </step>  
 <!-- Etat Validé-->  
 <step id="3" name="plugin.web:WORKFLOW_STATE_VALIDATED">  
            <actions>  
 <common-action id="2"/>  
 </actions>  
 </step>  
 </steps>  
</workflow>  

The above file is described for information purposes, but should not be modified outside the recommendations for integrating a new plugin. Indeed, it is not possible to use a new workflow without development Java.

Status (step)

A workflow state is defined by :

  • a unique numeric identifier (id attribute)
  • a name (name attribute)
  • une liste d'actions disponibles depuis cet état (balise <actions>)
  • des pré-fonctions (optionnelles) : fonction exécutées juste avant l'arrivée du contenu dans cet état (balise <pre-functions>)
  • des post-fonctions (optionnelles) :fonction exécutées juste après l'arrivée du contenu dans cet état (balise <post-functions>)

In Ametys, the report name is always a key i18n (see Internationalization).
If no catalog is defined, the translation of the key i18n must be found in the application catalog: WEB-INF/i18n/application.xml, WEB-INF/i18n/application_en.xml, ...

In addition to the i18n key for the state name, 2 other keys need to be created:

  • one for the state description, suffixed with _DESCRIPTION
  • one suffixed with _FOOTER

These i18n keys are used in Ametys for report tooltips.

Example with "Draft" status
<message key="WORKFLOW_STATE_DRAFT">Brouillon</message>  
<message key="WORKFLOW_STATE_DRAFT_DESCRIPTION">L'état 'Brouillon' est activé lorsque la version actuelle d'un contenu est dans un tel état.</message>  
<message key="WORKFLOW_STATE_DRAFT_FOOTER"></message>  

For example, here's the definition of a "Draft" state

<step id="1" name="plugin.web:WORKFLOW_STATE_DRAFT">  
 <actions>  
     <!-- Edition -->  
        <common-action id="2" />  
        <!-- Validation -->  
        <common-action id="4" />  
        <!-- Proposition -->  
        <action id="3" name="plugin.web:WORKFLOW_ACTION_PROPOSE">  
         <!-- Description de l'action de proposition -->         
        </action>  
 </actions>  
 <post-functions>  
     <function type="avalon">  
         <arg name="role">org.ametys.cms.workflow.CommentStepFunction</arg>  
        </function>  
    </post-functions>  
</step>  

In the example above,

  • 3 actions are available from the "Draft" state (state n°1): 2 common actions (editing and validation) and 1 action accessible only from this state (proposal)
  • 1 post-function is executed when this state is reached.

 

Functions are executed in the order of definition, so the order can be important!

The icons

In Ametys, a state is associated with 3 icons of different sizes, representing the state. Icon names are composed of the i18n key of the state name, suffixed with -small, -medium or -large depending on their size.

  • [STEPNAME]-small.png size 16x16 pixels
  • [STEPNAME]-medium.png size 32x32 pixels
  • [STEPNAME]-large.png size 48x48 pixels

The location of these icons depends on the i18n catalog used to define the report name:

  • if no catalog is specified, icons must be placed in the WEB-INF/param/workflow_resources directory
  • if a plugin catalog is specified, then icons must be placed in the plugins/ [plugin_name]/resources/img/workflow directory.

 

Actions or transitions

An action is a transition from one state to another.

A workflow action is defined by :

  • a unique numeric identifier (id attribute)
  • a name (name attribute)
  • a list of restrictions: a list of conditions that must be checked before the action can be executed. If one of the conditions is not met, the action is not available.
  • des pré-fonctions (optionnelles) : fonctions exécutées avant le changement d'état (balise <pre-functions>). Ne pas confondre avec les pré-fonctions d'état évoquées plus haut.
  • le résultat de l'action (<result>) : état dans lequel on aboutit lors de cette transition.
  • des post-fonctions (optionnelles) : fonctions exécutées après le changement d'état (balise <post-functions>)

As with reports, in Ametys, the action name must correspond to a key i18n.
If no catalog is defined, the translation of the key i18n must be found in the application catalog: WEB-INF/i18n/application.xml, WEB-INF/i18n/application_en.xml, ...

In addition to the i18n key for the action name, another key must be created for the description, suffixed with _DESCRIPTION.

<message key="WORKFLOW_ACTION_VALIDATE">Validation</message>  
<message key="WORKFLOW_ACTION_VALIDATE_DESCRIPTION">Cliquez ici pour valider le(s) contenu(s) sélectionné(s).</message>  

These i18n keys are used in Ametys for report tooltips.

For example, here is the definition of the validation action:

<action id="4" name="plugin.web:WORKFLOW_ACTION_VALIDATE">  
 <restrict-to>  
     <conditions type="AND">  
         <condition type="avalon">  
             <arg name="role">org.ametys.cms.workflow.ContentCheckRightsCondition</arg>  
                <arg name="right">Workflow_Rights_Validate</arg>  
            </condition>  
            <condition type="avalon">  
             <arg name="role">org.ametys.cms.workflow.LockCondition</arg>  
            </condition>  
            <condition type="avalon">  
             <arg name="role">org.ametys.cms.workflow.ValidateMetadataCondition</arg>  
            </condition>  
        </conditions>  
    </restrict-to>  
    <results>  
     <unconditional-result old-status=" " status=" " step="3" />  
    </results>  
    <post-functions>  
        <function type="avalon">  
         <arg name="role">org.ametys.web.workflow.ValidateContentFunction</arg>  
        </function>  
 <function type="avalon">  
         <arg name="role">org.ametys.cms.workflow.ValidationStepFunction</arg>  
        </function>  
 </post-functions>  
</action>  

In this example :

  • the validation action can only be carried out under 3 conditions:
    • the contributor has validation rights: org.ametys.cms.workflow.ContentCheckRightsCondition
    • content is not locked by another user: org.ametys.cms.workflow.LockCondition
    • all content metadata are valid (e.g. mandatory metadata): org.ametys.cms.workflow.ValidationStepFunction
  • the result of this action is to move the content to state n°3 (validated state)
  • 2 functions are executed following this action and the transition to state 3:
    • the current content version is marked as the last validated version (updated online content): org.ametys.web.workflow.ValidateContentFunction
    • the current state (n°3) is marked as the validation state: org.ametys.cms.workflow.ValidationStepFunction

Pre- or post-functions in Ametys

Here are the functions that can be called in an action, before or after the state change:

Functionpre-functionpost-functionRole
org.ametys.web.workflow.CreateContentFunctionx Creates content.
Do not use elsewhere than in the initial action.
org.ametys.cms.workflow.SetCurrentStepFunction xSets the "ametys-internal:currentStepId" property representing the current state.
To beused as a post-function in most actions, except for validation and depublication actions.
org.ametys.cms.workflow.CreateVersionFunction xCreates a new version of the content.
Use for all actions requiring the creation of a new version (creation, editing, restoration, etc.).
org.ametys.cms.workflow.EditContentFunctionx Saves changes made to content.
To beused in the editing action.
org.ametys.plugins.forms.workflow.FormEditionFunction xFinds Ametys forms present in the content and saves them in the database.
Foruse in the edit action.
org.ametys.web.workflow.ValidateContentFunction xValidates the current version of the content so that it can be put online.
To beused in the validation action.
org.ametys.cms.workflow.ValidationStepFunction xMarks the current state as the validation state.
To beused in the validation action.
org.ametys.cms.workflow.RestoreRevisionFunctionx Restores an older version of the content.
To beused in the restore action.
org.ametys.web.workflow.UnpublishContentFunctionx Removes the information specifying that the content is validated.
Warning! It is imperative that the associated action removes the content from the validated state, otherwise the contributor will be confused.
To beused in archiving and unpublishing actions.
org.ametys.cms.workflow.MarkContentArchivedFunctionx 

Places or removes content from archive space. The "unarchive" argument set to "true" indicates that the content is to be removed from the archive space.
To be used in the archive action with no argument and in the unarchive action with the unarchive= true argument.

<function type="avalon">  
 <arg name="role">org.ametys.cms.workflow.MarkContentArchivedFunction</arg>  
    <arg name="unarchive">true</arg>  
</function>  
org.ametys.cms.workflow.SetProposalDateContentFunctionx 

Sets or removes the content proposal date.
To be used in the proposal action with no argument and in the validation refusal action with the remove= true argument.

<function type="avalon">  
      <arg name="role">org.ametys.cms.workflow.SetProposalDateContentFunction</arg>  
      <arg name="remove">true</arg>  
</function>  
org.ametys.web.workflow.SendMailToUserFunction  x

Sends an e-mail to the person who performed the previous action.
This function is used with 2 arguments:

  • "subjectkey" refers to a i18n key to determine the subject of the mail message. In the i18n key translation, you can use the {1} parameter for the content title
  • "bodyKey" refers to a key i18n to determine the body of the mail

The i18n ""bodyKey"" key must actually be broken down into 3 keys in the catalog: 

  • [I18N_KEY]: for the normal case of content inserted in a page
  • [I18N_KEY]_ORPHAN: if the content concerned by the action is orphaned, i.e. not attached to any page
  • [I18N_KEY]_NOSITE: if the content concerned by the action is not linked to a site (e.g. training content)

For each translation you can use the following parameters:

  •  {0} user name
  • {1} content title
  • {2} site title for keys [I18N_KEY] and [I18N_KEY]_ORPHAN, or url of CMS for key [I18N_KEY]_NOSITE

  • {3} page title for key [I18N_KEY] or link to content for key [I18N_KEY]_ORPHAN

  • {4} link to content page for key [I18N_KEY]

Example

<!-- // Fichier workflow.xml -->  
<function type="avalon">  
 <arg name="role">org.ametys.web.workflow.SendMailToUserFunction</arg>  
    <arg name="subjectKey">plugin.web:WORKFLOW_MAIL_SUBJECT_ACTION_REFUSE_PROPOSITION</arg>  
    <arg name="bodyKey">plugin.web:WORKFLOW_MAIL_BODY_ACTION_REFUSE_PROPOSITION</arg>  
</function>  

<!-- // Fichier messages_fr.xml -->  
<message key="WORKFLOW_MAIL_SUBJECT_ACTION_REFUSE_PROPOSITION">Refus de validation du contenu "{0}"</message>  
<message key="WORKFLOW_MAIL_BODY_ACTION_REFUSE_PROPOSITION">L'utilisateur {0} a refusé la demande de validation du contenu "{1}" sur la page "{3}" du site "{2}". Le contenu est de nouveau en cours d'édition.  

Pour vous rendre sur la page cliquez sur le lien ci-après {4}.</message>  
<message key="WORKFLOW_MAIL_BODY_ACTION_REFUSE_PROPOSITION_ORPHAN">L'utilisateur {0} a refusé la demande de validation du contenu "{1}" du site "{2}". Le contenu est de nouveau en cours d'édition.  

Pour vous rendre sur le contenu cliquez sur le lien ci-après {3}.</message>  
<message key="WORKFLOW_MAIL_BODY_ACTION_REFUSE_PROPOSITION_NOSITE">L'utilisateur {0} a refusé la demande de validation du contenu "{1}". Le contenu est de nouveau en cours d'édition.  

Pour vous rendre sur le CMS cliquez sur le lien ci-après {2}.</message>  
   
org.ametys.web.workflow.SendMailFunction x

Sends an e-mail to people with the rights defined in the function's "rights" argument, for the content in question.

The "subjectkey" and "bodykey" arguments follow the same rules as for SendMailToUserFunction (see previous line).

Example

<!-- // Fichier workflow.xml -->  
<function type="avalon">  
 <arg name="role">org.ametys.web.workflow.SendMailFunction</arg>  
    <arg name="rights">Workflow_Rights_Validate, Workflow_Rights_Notification</arg>  
    <arg name="subjectKey">plugin.web:WORKFLOW_MAIL_SUBJECT_ACTION_PROPOSE</arg>  
    <arg name="bodyKey">plugin.web:WORKFLOW_MAIL_BODY_ACTION_PROPOSE</arg>  
</function>  

<!-- // Fichier messages_fr.xml -->  
<message key="WORKFLOW_MAIL_SUBJECT_ACTION_PROPOSE">Contenu "{0}" proposé</message>  
<message key="WORKFLOW_MAIL_BODY_ACTION_PROPOSE">L'utilisateur {0} a proposé pour validation le contenu "{1}" sur la page "{3}" du site "{2}". Le contenu est en attente de validation.  

Pour vous rendre sur la page et valider le contenu cliquez sur le lien ci-après {4}.</message>  
<message key="WORKFLOW_MAIL_BODY_ACTION_PROPOSE_ORPHAN">L'utilisateur {0} a proposé pour validation le contenu "{1}" du site "{2}". Le contenu est en attente de validation.  

Pour vous rendre sur le contenu et le valider cliquez sur le lien ci-après {3}.</message>  
<message key="WORKFLOW_MAIL_BODY_ACTION_PROPOSE_NOSITE">L'utilisateur {0} a proposé pour validation le contenu "{1}". Le contenu est en attente de validation.  

Pour vous rendre sur le CMS cliquez sur le lien ci-après {2}.</message>  
    

To find out more
An action can contain a finish="TRUE" attribute: this defines the end of the workflow and refers to an empty step, which is generally commented out (this avoids reusing the end step identifier, which could cause problems!).

To find out more
When it comes to content validation, there are several technical concepts that need to be linked within a coherent workflow file.
1) The workflow life cycle. The wording of states (Draft or Validated, for example) carries information for the contributor, but does not technically allow them to have a meaning: this semantic meaning is given to them through the functions (state or action) associated with these states.
2) The "Live" indicator placed on a content version. At any given moment, a maximum of one version of the content history can carry this indicator, i.e. the version that is visible on the site to visitors. For consistency, this flag should be set when the "Validated" workflow state is reached. The ValidateContentFunction is responsible for this. This flag can be removed by the UnpublishContentFunction.
3) The "validation" flag set in the workflow history. This flag is set for each validated version: for example, it allows the history to visually highlight validated versions, or the purge to keep only validated versions of content. The ValidationStepFunction is responsible for this.
A consistent workflow is therefore, for example, one in which a validated state always uses the ValidateContentFunction and the ValidationStepFunction.
With regard to archiving, it should be noted that archived content passes into another content space (see the User Manual, Content archiving). The MarkContentArchivedFunction is therefore necessary, as it is this function that performs the move.

Be careful when modifying the workflow of an existing project, as content and its history have already been entered. In this case, you must not delete steps and actions already defined, nor modify their identifiers, as they are potentially referenced (and this would cause inconsistencies and errors in the display of the history, for example). It is also important to check that no content is currently in the state to be deleted: otherwise, no action will be available to get out of it.
It is therefore recommended to visually hide the actions associated with these states or actions.

Workflow conditions in Ametys

Voici ci-dessous les conditions de workflow (<restrict-to>) disponible dans Ametys :

ConditionRole
org.ametys.cms.workflow.ContentCheckRightsCondition

Checks that the user has the right to the content passed as an argument.

<condition type="avalon">  
 <arg name="role">org.ametys.cms.workflow.ContentCheckRightsCondition</arg>  
    <arg name="right">Workflow_Rights_Edition_Online</arg>  
</condition>  
org.ametys.plugins.workflow.component.CheckRightsConditionChecks that the user has the right passed as an argument on the application context
org.ametys.cms.workflow.LockConditionChecks that content is not locked by another user.
org.ametys.cms.workflow.ValidateMetadataConditionChecks that all content metadata is valid

 

Workflow buttons in the ribbon

In the demo application Ametys, the plugin "default-workflow" defines the buttons associated with workflow states and actions, which are displayed in the ribbon.

There are 2 possible extensions for workflow actions and states:

  • org.ametys.cms.clientsideelement.SmartContentClientSideElement
    This extension is used for buttons that perform a workflow action. For example: Modify content, Unpublish, ...
    The button will be grayed out if the workflow action is not available.

  • org.ametys.cms.clientsideelement.WorkflowMenu
    This extension is used to represent the current state of the workflow. The menu appears when the content is in the corresponding state (Draft, Proposed, Validated, ...). The menu displays the workflow actions available from this state.


 

To find out more
On the Overload workflow buttons page, you'll find out how to overload these buttons.

Example exercise

As an example, we'll take the demo version workflow and remove the Proposed status.

We therefore start with the following buttons:

In the case of a blank project (with no existing content), simply :

  1. delete the button in the ribbon: file WEB-INF/param/cms-ribbon.xml, delete the lines displaying the "Proposed" menu (identifier org.ametys.web.workflow.Proposed) 
  2. delete the button definition in plugin default-workflow
  3. delete the "Proposed" status and the "Propose" action from the workflow itself in the WEB-INF/param/workflow file.xml, delete (or comment out...) action 3 defined in step 1, and delete step 2.

We now have the following buttons:

 

Dans le cas d'un projet existant (avec des contenus existants) il faut faire comme ci-dessus mais au niveau du fichier de workflow, il faut simplement retirer l'action "Proposer" de l'action d'état "Brouillon" et la transférer dans les actions communes (<common-action>); ainsi l'action "Proposer" n'est plus disponible depuis l'état de "Brouillon", mais elle existe quand même : l'historique restera cohérent alors même que l'action semble de plus exister pour les contributeurs.

Back to top