Out of the box, Drupal offers some great tools for content moderation and basic editorial workflows. It is simple and flexible by design because there is no one-size-fits-all solution for every organization and editorial team. Drupal prefers to provide the tools. Your team can figure out how best to use those tools.
Publishing workflows and strategies are complex subjects, but we'll go over the fundamental concepts of how Drupal handles these concepts.
The basic concepts
Let's start by refreshing some fundamental concepts that are the basis of Drupal's entity storage and what its data models are based on.
Entities
Most content in Drupal is stored under the hood in buckets we call "Entities," and these entities have fields (or properties.) "User" is an entity, and "User name" is a field of that entity. Nodes are a special type of entity, expected to model most of the site's standalone pages in Drupal.
Revisions
Most content stored in entity fields is revisionable. This means that these entities will have an ID and a Revision ID. This is what allows you to create different versions of the same content.
Currently, Drupal has the "Create new revision" setting marked by default on Content Types (nodes), so if you don't configure anything else explicitly, then your site will generate a new revision each time the editor saves the node form. Because of that, after a couple of edits, a new "Revisions" tab will be available to users with the appropriate permissions, allowing them to check the history of revisions for that particular piece of content.
Note: if you install the Diff module, this page will also allow you to compare two revisions, checking what the actual content differences are.
Bonus tip: Use the Revision Log Default module to ensure that revisions always have a log message.
The "Current revision" (or, more technically, "Default revision") of a particular piece of content is the concept that Drupal uses to define "what version (revision) of this content should I load when a specific revision is not specified." This is the revision you get, for example, when:
- a user visits
/node/123
- an editor opens the node edit form (in a standard Drupal setup)
- a field references a related node only by the node ID (more on this later),
- you load an entity in custom code with something like:
$node = \Drupal::entityTypeManager->getStorage('node')->load(123);
The reference to which revision is the "default" one is stored in the column vid
of the base entity table (for nodes, this means the node
table).
The "Revert" action (also referred to as "Roll-back") will generate a new revision and set it to be the new default revision. The contents of this new revision will be copied from the past revision you selected to revert to. Note that without Content Moderation, the default revision will always be the latest revision created.
Publishing status
All nodes (and most content entities) in Drupal have a status
property that defines whether that particular piece of content should be "publicly visible" or not. Out of the box, Drupal content can have a status of "published" or "unpublished." You could modify this behavior by allowing different roles access to unpublished content, but that's the general idea.
In a standard Drupal setup (i.e., without Content Moderation), once what is loaded in the edit form is the default revision, publishing or unpublishing a node will always affect the default (and also the latest) revision of that content.
Increase the complexity with Content Moderation
The functionalities described above allow some basic control over the publishing status of the content but fall short when sites need to implement more advanced editorial workflows. For example, if you need to have your content go through several unpublished (but different) states before it gets published, or when you have a published page, and you need to get modifications on it approved by stakeholders before making them public.
The Content Moderation module from Drupal core brings some significant changes to the basic functionality we saw above, the most important ones being workflow states and forward revisions.
Workflow states
If you have experimented with the Content Moderation module, you have already discovered that it depends on the Workflows module, where the concepts of "Workflow states" and "Transitions" are defined. With these modules, you can define arbitrary paths that describe the life cycle of the content on your site.
For example, by default, the Content Moderation module creates the "Editorial" workflow with three states: draft, archived, and published. The workflow defines which states can flow to other states.
As you can imagine, you can modify both the states and transitions of this workflow to suit your specific needs. You can also create additional workflows with different states that could apply to a subset of your content while using the "Editorial" workflow for others. For example, your Press Release content type might need to go through an extra round of approval that other content types don't need.
Forward revisions
A key aspect of Content Moderation is the ability to have future (or forward) revisions. This means that the default revision is not necessarily the most recent one anymore. Additionally, you can associate the publishing status of the content with one or more workflow states.
When using Content Moderation, Drupal will show on your site the most recent revision that is in one of the "published" states.
You could configure some states to trigger the default revision without being a published state, but that is a non-standard configuration that should be avoided in most scenarios.
So after enabling Content Moderation, defining your workflow states/transitions, and assigning this workflow to your content entity (check the documentation for more info on how to do this), your editors now have different features when creating content:
The "Revisions" tab also shows an important difference. New drafts are shown in the list above the published "default revision."
Users with the appropriate permissions will be able to see a "Latest version" tab on the node pages (also available under the URL: /node/123/latest
).
This is the content that will be loaded when users open the node edit form and is ultimately the content being "moderated," as opposed to the "published" content, which visitors would typically see when visiting /node/123
. In most scenarios, content with no unpublished revisions pending approval (i.e., no forward revisions) has the default revision as its "Latest version." In those cases, this tab is not shown.
Bonus Tip: You can use the modules Moderation Sidebar and Moderation Note to improve the user experience of your editors while transitioning content between states in the workflow.
Conclusion
Those are the basics of revisions and content moderation. Of course, figuring out how to use these tools for your own needs is an entire topic in itself. The possibilities are almost endless.
Because Drupal is so good at complex, structured content, one of the traps you can fall into is making assumptions about how revisions work for reusable components and content that refers to other content. Most Drupal sites make use of entity reference fields for this purpose. But there are dangers in making assumptions. In the next article, we'll discuss some of those dangers, particularly when inline editing embedded content is involved.