This blog post suggests a technique for setting field values programmatically in entries as they move through workflows in SaaS headless content management systems, specifically considering my experiences with the Contentstack SaaS headless CMS. Full disclosure: I wrote it some time ago, moved on, forgot about it, never reviewed it, and published it to clear out of the drafts folder without losing its content. Take it for whatever it might be worth.
Many CMS use cases involve systems setting field values automatically. For example, when a user creates an entry that represents a news article, the system can default the value of a date field associated with its publication to the current date. In other cases, the system sets fields after users have begun data entry, for example defaulting an end date based on a start date.
Setting any field value, including the field used to store the current workflow stage, creates a new version, which increments the number of versions each time an entry moves from one workflow stage to another and prompts the CMS user to load or compare the new version.
You can use webhooks to invoke logic that updates field values when users save entries, but this has some disadvantages. Invoking certain logic for each save operation can have performance implications. Additionally, because the CMS UI refreshes before webhook handlers complete, the UI renders the version and values stored by the user rather than those updated by the code and prompts the user to load or compare that new version to the one they are editing.
You can use workflow stages to simplify the implementation and reduce annoyances. The general approach is to use a global field included in the content type to store the identifier of the workflow stage. If the value of the field matches the current workflow stage of the entry, then the webhook handler does nothing. If the value of the field is blank or does not contain the current workflow stage of the entry, then the webhook handler updates that field the current workflow stage along with other changes to the entry. Otherwise (if the value of the field is not blank and matches the current workflow stage of the entry), the webhook handler does nothing.
This logic handles both entry creation and workflow transitions. For example, when a CMS user creates an entry, you can set date fields to the current date plus some number of days, which will prompt the user to load the version that contains those values. When a user moves an item from one workflow stage to another, the current user may see a prompt to load those changes. Any users that take ownership of the entry afterwards will access the latest version with the most current values.
You can set the value of a text field to pass messages to the CMS user, such as data validation issues that the webhook handler cannot address. You can use this technique to validate fields of content types where the user may not be able to enter all the data at entry creation time. You can use publishing rules to prevent publication of entries with validation issues. Note that users with appropriate access can change the value of the field used for validation messages, which could allow publication of invalid data. You use field visibility rules to hide this field and use a widget to render its value. You may also want to use field visibility rules to hide the field that stores the most recent workflow stage for the entry.
This solution depends on workflow, which may not be appropriate for all use cases.
After implementing a prototype, it seems more appropriate but more complicated, expensive, and obtrusive to the CMS user to apply the webhook handler logic after each entry save operation. Maybe the handler could fire only for save operations while the entry is in one or more workflow states (for example, validate), though this would require additional logic (such as storage of a the date and time of the last validation and aborting validation unless some amount of time has passed since the last validation). Widgets may be more appropriate for validation, especially if they can set field values programmatically and refresh the UI afterwards to load those changes.
If you have suggestions for setting field values programmatically entries with or without workflow, please comment on this blog post.