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 theWEB-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:
Oops!
Copy to clipboard failed. Open the code and copy it manually.
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 )
Oops!
Copy to clipboard failed. Open the code and copy it manually.
<message key="WORKFLOW_bpm-default">Processus avec double validation expert/élus</message>
<message key="WORKFLOW_bpm-default">Processus avec double validation expert/élus</message>
<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
Oops!
Copy to clipboard failed. Open the code and copy it manually.
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
Oops!
Copy to clipboard failed. Open the code and copy it manually.
<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>
<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>
<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
Oops!
Copy to clipboard failed. Open the code and copy it manually.
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.
Oops!
Copy to clipboard failed. Open the code and copy it manually.
<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>
<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>
<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:
Oops!
Copy to clipboard failed. Open the code and copy it manually.
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:
Function
pre-function
post-function
Role
org.ametys.web.workflow.CreateContentFunction
x
Creates content. Do not use elsewhere than in the initial action.
org.ametys.cms.workflow.SetCurrentStepFunction
x
Sets 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
x
Creates 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.EditContentFunction
x
Saves changes made to content. To beused in the editing action.
Finds Ametys forms present in the content and saves them in the database. Foruse in the edit action.
org.ametys.web.workflow.ValidateContentFunction
x
Validates the current version of the content so that it can be put online. To beused in the validation action.
org.ametys.cms.workflow.ValidationStepFunction
x
Marks the current state as the validation state. To beused in the validation action.
org.ametys.cms.workflow.RestoreRevisionFunction
x
Restores an older version of the content. To beused in the restore action.
org.ametys.web.workflow.UnpublishContentFunction
x
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.
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.
Oops!
Copy to clipboard failed. Open the code and copy it manually.
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.
Oops!
Copy to clipboard failed. Open the code and copy it manually.
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
Oops!
Copy to clipboard failed. Open the code and copy it manually.
<!-- // 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>
<!-- // 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>
<!-- // 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
Oops!
Copy to clipboard failed. Open the code and copy it manually.
<!-- // 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>
<!-- // 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>
<!-- // 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 :
Checks that the user has the right passed as an argument on the application context
org.ametys.cms.workflow.LockCondition
Checks that content is not locked by another user.
org.ametys.cms.workflow.ValidateMetadataCondition
Checks 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 :
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)
delete the button definition in plugin default-workflow
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.