Custom workflows have been already requested several times and we will work on it in 2019, but until then this guide will teach you how to implement custom workflows. It will provide a setup that can be much more flexbible than what we are planing.
In our scenario we manage articles and have three roles:
Creators: Writes articles and when they are done they mark an article as Ready
.
Reviewers: Reviews articles and either mark an article as Approved
or Rejected
.
Publisher: Decides when to publish an article and should only publish approved articles.
Therefore we have 3 states for content:
Draft
Ready
Approved
Rejected
Published
The following diagram vizualizes our workflow.
In the first step we create a schema. We keep it simple and define 3 fields:
Title: The title of the article.
Status: The status of the article as string field with a dropdown editor.
Text: The text as markdown.
We will make set the first two fields as list fields, which means we will see them in our content lists.
The schema in the UI:
.
I will not show everything in this tutorial, it is just too much and the solution is the same for all roles, but we will show you how we implemented it for the Creator
:
The solution is scripting. If you click the three dots in the schema editor a menu will pop up with a menu item to the scripting editor. Here you can define scripts that are invoked when a content item is queried, created, updated, deleted or when the status is changed.
The script for creating content is very simple:
// Check the status field is set to draft.if (ctx.data.status.iv !== 'Draft') {// If not reject this operation with a custom validation message.reject('The status of a new article must be set to Draft');}
Thats it, we do not have to do more, because the permission system already enforces that only Creators
can create content.
The UI will show the error message from the script:
Lets have a look to the update script:
// Our code for the Creatorif (ctx.user.claims.role.indexOf('Creator')) {// Check the old status of our content.if (ctx.oldData.status.iv !== 'Draft' && ctx.oldData.status.iv !== 'Rejected') {disallow('You are not allowed to edit content that has been published already.');}​if (ctx.data.status.iv !== 'Draft' && ctx.data.status.iv !== 'Ready') {reject('You only set the status to Draft or Ready');}}
What we do:
We check if the current user is a Creator
.
If the content has the wrong status we cancel the process with the disallow
function. Then the API responds with a HTTP 403: Forbidden
and the UI will show an error message.
if the content is changed to an invalid status we cancel the update with the 'reject' function. Then the API respons with a HTTP 400: Bad Request
and the UI will show the error message.
The rest of the requirements can be implemented with a some more if
-statements.
You can already implement custom workflow with Squidex, but this solutions has several small issues:
You have a second field for the status of the addition.
The user experience could be better.
You have to define, write and define the scripts.
But on the other side there are also some points on the PRO side:
You can implement very fine grained workflows and you are not restricted by a built-in solution.
You can even make the Status field localizable and ensure that all texts are reviewed from different person before you publish a content.