Multi-workflow support for Plone

Some content has more than one lifecycle at a time. A person's profile is published or private, and — quite separately — their Foundation membership is pending, active or lapsed. An organization is published, and separately it is listed or verified.

Plone has one answer for that today: review_state. So we fold both lifecycles into one workflow and multiply its states, split the content into two types, or drop the second lifecycle into a plain field and give up guards, transition permissions, history and role mappings.

The odd part is that the machinery for doing better has been in CMF all along. portal_workflow supports a chain of workflows, getChainFor resolves it through a multi-adapter, and DCWorkflow keys status records by workflow id. What is missing is everything around it — the catalog, plone.api, plone.restapi, the history viewlet, Volto — all of which read review_state and stop there.

I wrote up the whole story here:

:link: Published and pending: multi-workflow support for Plone

The add-on

collective.multiworkflow makes a chain usable across the stack, driven by behaviors rather than by editing portal_workflow type by type:

<plone:additionalworkflows
    marker=".behaviors.IMembership"
    workflows="membership_workflow"
    label="Membership"
    />

Contributed workflows are appended, never substituted, so review_state keeps meaning what it means today and content without the behavior is served exactly what Plone has always served. One catalog index covers the whole chain, @workflow gains a chain key, and the companion Volto add-on renders a selector per workflow.

It is 1.0.0a2, so alpha, and collective.casestudy is the worked example to read. Details and install instructions are in the documentation.

The PLIP

An add-on is the wrong long-term home for this — it only works by overriding plone.restapi services, shadowing Volto components and monkey-patching plone.exportimport, all of which disappears if the change lands in core.

So the design is also filed as a PLIP, targeting Plone 6.3:

PLIP: Additional workflows contributed by behaviors

It is still [WIP], it still needs a seconder, and the issue carries a list of open questions I would genuinely like opinions on. If you have ever wanted two workflows on one content item — or you think this is the wrong shape entirely — that issue is the place to say so.

7 Likes

Very nice! And it still surprises me how many features the WorkflowTool has.

Are you planning to change the indexing of <workflow-id>|<state-id>? Right now it is a single value, so searching for a workflow-id or state-id isn't easy; that means you're mostly working with objects related to the same workflow across almost all known folders, right?

1 Like

I chose the <workflow-id>|<state-id> approach so queries could target a specific workflow and state combination. You raise a valid point, though: for queries by state alone, review_state still works as it does today, and I don't plan to change it.

That said, review_state has a limitation. Its vocabulary merges terms with the same token and keeps the last title, which gives the result below:

The first option is the approved state, which the current plone.org uses in two distinct workflows:

The title shown is the one from foundation_sponsor_workflow, even though I'm filtering Foundation Members here.

With <workflow-id>|<state-id>, that ambiguity goes away, because each combination is its own term.

(And I admit UX was one of the main reasons to get the new approach going)

1 Like