How to search by an additional workflow state#

This guide shows you how to find content by its state in any workflow of its chain.

Prerequisites#

  • The add-on installed, and content in at least one additional workflow.

Query the index from code#

Query workflow_states, building the value with format_state.

from collective.multiworkflow.utils.workflow import format_state
from plone import api

active = api.content.find(
    workflow_states=format_state("foundation_member_workflow", "active")
)

workflow_states is a KeywordIndex, so a list of values matches any of them.

results = api.content.find(
    workflow_states=[
        format_state("foundation_member_workflow", "active"),
        format_state("foundation_member_workflow", "pending"),
    ]
)

To require several states at once—published and an active member—pass the and operator.

results = api.content.find(
    workflow_states={
        "query": [
            format_state("simple_publication_workflow", "published"),
            format_state("foundation_member_workflow", "active"),
        ],
        "operator": "and",
    }
)

Read a value back#

Use parse_state rather than splitting the string yourself.

from collective.multiworkflow.utils.workflow import parse_state

for brain in active:
    for value in brain.workflow_states:
        workflow_id, state_id = parse_state(value)

The metadata column is available on brains, so this needs no object wake-up. Values are in chain order, and the first is always the workflow driving review_state.

Read the states from a search request#

Summaries of catalog results carry workflow_states, so a search returns every item's states with no further request.

GET /plone/@search?portal_type=Profile HTTP/1.1
Accept: application/json

Each item of the response holds a workflow_states list, in the same format and order as the index. The serialization of a single object carries the same key. See Content serialization.

Add a criterion to a collection#

In the collection editor, choose the Review state criterion. Its vocabulary lists every state of every registered workflow, titled <workflow>: <state>, so an additional workflow's states are selectable there with no further configuration.

What happens to existing review_state criteria#

A criterion written before the add-on was installed keeps working.

A parsed review_state query whose values name no workflow, such as published, is left on the stock review_state index and answers exactly as before. Only a query carrying a qualified value is moved onto workflow_states, with the operator of an all of criterion and the negation of an excludes criterion preserved. A criterion saved from the collection editor carries qualified values, so it is moved from then on.

You do not need to rewrite stored collections.

Note

Code that queries review_state through portal_catalog directly is not rewritten—only parsed collection queries pass through the modifier. Direct catalog queries against review_state continue to work, because the stock review_state index is still there and still maintained by the publication workflow.

If a query returns nothing#

Check that the index is populated.

catalog = api.portal.get_tool("portal_catalog")
assert catalog.Indexes["workflow_states"].numObjects() > 0

An empty index on a site with content means the objects were never indexed under it—see How to add the package to an existing site.

See also

Catalog index for the exact rules, and About the workflow_states index for why they are these rules.