Catalog index#

The default profile adds one KeywordIndex named workflow_states to portal_catalog, along with a metadata column of the same name. One index describes an object's whole chain, so a site gains no further indexes as behaviors contribute more workflows.

Indexed values#

Each value reads <workflow-id>|<state-id>.

simple_publication_workflow|private
foundation_member_workflow|active

The following rules hold for every indexed object.

  • Values are in chain order. The first value is always the workflow that drives review_state, whether or not anything was contributed to the object.

  • The separator is |. Neither a workflow id nor a state id can contain it, because both are Zope ids.

  • An object with no workflow at all indexes nothing.

Build a value with format_state, and read one back with parse_state. Do not assemble or split the string by hand.

The name is also a state variable#

workflow_states is both the name of the index and the state_variable an additional workflow should declare.

That is not cosmetic. WorkflowTool._reindexWorkflowVariables reindexes exactly the indexes named after the chain's workflow variables, so a workflow using this name keeps the index fresh with no further help. A workflow that keeps a state variable of its own is covered instead by the reindex_workflow_states event handler, which reindexes only when nothing else will.

Sharing one name across several workflows is safe: DCWorkflow keys its status records by workflow id, not by variable name.

How the index is kept fresh#

Three mechanisms, covering three ways an object's state can change.

Transitions

WorkflowTool._reindexWorkflowVariables reindexes the indexes named after the chain's workflow variables. This covers every workflow that declares workflow_states as its state variable, at no cost.

The reindex_workflow_states event handler

Covers a workflow that keeps a state variable of its own, which the mechanism above would not reindex. It acts only when nothing else will, because a partial reindex rebuilds the object's entire metadata record.

The plone.exportimport patch

Covers content whose state arrives by import rather than by transition. plone.exportimport restores workflow state by assigning workflow_history directly, which fires no transition and so reaches neither mechanism above. See collective.multiworkflow.exportimport.

Important

What the catalog stores is always the indexer, never the workflow variable that happens to share its name. plone.indexer's wrapper consults IIndexer adapters before it consults workflow variables.

Query rewriting#

A parsed collection query against review_state is redirected to workflow_states by ReviewStateModifier, registered as an IParsedQueryIndexModifier.

The rewriting is value-aware.

  • A bare state id, such as published, is qualified with the first workflow of the site's default chain. A stored collection written before this package was installed therefore keeps working.

  • An already-qualified value is passed through unchanged.

  • A value that is not a string—a date range, say—is passed through unchanged.

  • Keys other than query and not are preserved, so the and operator of an all of criterion and the negation of an excludes criterion both survive.

A site that declares no default chain has nothing to attribute a bare id to, and the value is passed through unchanged.

Vocabulary#

collective.multiworkflow.vocabularies.WorkflowStates provides one term per state of every registered workflow. Terms are keyed exactly as the index holds them, and titled <workflow title>: <state title>.

The default profile makes it the value source of the existing Review state query field, replacing the vocabulary of plain review_state values. The collection editor therefore offers every state of every workflow under the criterion editors already know, and the values it stores are qualified ones that ReviewStateModifier passes through untouched.