Work on the web long enough, and you’ll eventually need some sort of workflow. Something that allows some users to make certain changes, and other users to review those changes before they’re live for all the world to see. Unfortunately, this is something that’s long been hard to set up in WordPress.
In 2015, St. Mary’s needed what seemed like a fairly straightforward workflow for a new Policy Library website. This site would become our repository for official University policies, not only centrally collecting policies that were previously scattered in various digital and print forms, but also becoming our official record of who edited what when. The idea was, each office would have one Policy Editor who could create new policies, but once they submitted their policies for review, they’d be held in a pending state until the Policy Approver for that office approved and published them.
That’s the most straightforward part of the workflow, and you can (kind of) set it up using WP core. However, it falls short in a couple of places.
For one thing, if you set up the Policy Editors as Core’s “Contributor” role, they’re able to create new posts but not edit them once they send them out for review. Our Policy Editors needed to be able to make changes to existing policies. For another thing, Core roles have access to all post types by default, so our Policy Approvers could approve any sort of policy – even those outside their assigned area.
Added to this, the real dilemma with WordPress workflows is what happens once a post is published. Core behavior is that if anyone who has edit rights but not publish rights can edit a published post, but once they save it, it reverts to “pending” status, meaning the published version is actually unpublished and the public can no longer view it. Our policies had to stay published even when there were edits pending.
Finally, our users aren’t in WordPress very often, so we also wanted to enable notifications. This ended up being: Policy Approver receives an email whenever a Policy Editor submits a new policy or edits for review; and Policy Editor receives an email whenever a Policy Approver publishes changes. Thankfully for this part, WordPress has a number of hooks, notably post status transition hooks.
It’s hacky, but it works
Eventually, we cobbled together a solution that met the basic requirements. But like any IT project, there was scope creep. Where the requirements defined exactly one Policy Editor and one Policy Approver for each office, everything became muddy when we realized that some people needed to have access to several offices’ policies. That would have been easy to solve in a poor-user-experience way, with those users having a separate login for each role, but (1) we didn’t want to impose that kind of login management on anyone and (2) we wanted to use single sign-on, which in our ecosystem would mean each person would have to have a single login.
So, we cobbled things together a bit more, and using a couple of plugins we sort of enabled people to access what they needed to access. But the users with multiple roles kept having issues – one plugin would conflict with another, so that in just the right conditions, those users ended up with no roles at all. Obviously that had to be fixed.
Then in 2017, there was a lot of talk about this new thing called Gutenberg. Nobody knew exactly when, but it was coming. Its development was so rapid and so poorly documented during development that we opted to fix the problems we had with the Classic Editor and deal with the Block Editor later. But like any IT project, there kept being so many other IT projects that eventually the goals coalesced, which brings us to today.
Once Gutenberg became part of Core, it was time to start working on Policy Library 2.0. This new version would be Block Editor compatible, eliminating Policy Editors’ previous need to edit everything in Word and then try to paste in lengthy, complexly-formatted documents. It would also solve the multiple-role issues of the past. It would better hook into WordPress’ own functionality instead of hijacking it in some places, and we would share our attempts with the world.
At WordCamp US 2018, it was revealed that workflow is one of the features WP Core will be tackling in the next couple of years, as Gutenberg becomes more than just the editor. I am hopeful that by sharing what we have tried and learned, we might spark community thoughts on how to make workflow much easier to implement, and what the best way is to add it as a Core feature.
So where are the juicy details?
I’ve broken up Workflow 1.0 and Workflow 2.0 into multiple posts, so that instead of just typing up long paragraphs of theory, you can see the code we’ve used and the overall processes we’ve put in place. This post serves as the table of contents so you can peruse whichever parts are relevant to your interests, but it makes more sense if you go through the articles in the following order:
- Workflow: the vision – an explanation of the workflow we wanted to achieve
- Workflow 1.0: creating the CPTs and roles – the first step to creating our workflow
- Workflow 1.0: creating the workflow – the nitty-gritty details
- Workflow 2.0: creating the CPTs and roles – updated a bit from 1.0
- Workflow 2.0: creating the workflow – the new approach
- Workflow 2.0: Making it easier – widgets and post columns