How to install the worked example#

This guide shows you how to load collective.multiworkflow.demo, a worked example of a behavior contributing a workflow.

The example gives you a Profile content type whose membership status is tracked by a foundation_member_workflow running alongside publication. Use it to see the mechanism working before you write your own, and as a reference for the shape of a real declaration.

Prerequisites#

1. Load the demo package's ZCML#

The root configure.zcml never includes the demo subpackage, so neither the behavior nor its profiles exist until you load it explicitly. That is deliberate: installing the add-on must not touch a site's content types.

If your instance is generated by cookiecutter-zope-instance, add the subpackage to the includes.

default_context:
    zcml_package_includes: 'my.policy,collective.multiworkflow.demo'

Otherwise include it from your policy package's configure.zcml.

<include package="collective.multiworkflow.demo" />

Restart the instance. ZCML is read at start-up, so the new behavior and profiles appear only after a restart.

2. Apply the demo profile#

Install Multi-Workflow Support for Plone: Example behavior from the add-ons control panel, or apply it directly.

from plone import api

setup_tool = api.portal.get_tool("portal_setup")
setup_tool.runAllImportStepsFromProfile(
    "profile-collective.multiworkflow.demo:demo"
)

This adds the Profile content type with the collective.multiworkflow.demo.foundation_member behavior enabled, and installs the membership workflow it contributes.

3. Add the example content, if you want it#

The example content lives in a second profile.

setup_tool.runAllImportStepsFromProfile(
    "profile-collective.multiworkflow.demo:content"
)

Warning

The importer behind this profile commits as it goes. Never apply it from an integration test layer: the per-test rollback cannot undo those commits, and the content will leak into every test that follows.

4. See the chain#

Create a Profile object, then read its chain.

from collective.multiworkflow import api as mw_api
from plone import api

portal = api.portal.get()
profile = api.content.create(
    container=portal, type="Profile", title="A Member"
)

assert mw_api.get_states(profile) == {
    "simple_publication_workflow": "private",
    "foundation_member_workflow": "pending",
}

Two workflows, two independent states. Transition the membership workflow and the publication state does not move.

mw_api.transition(
    profile, "activate", workflow_id="foundation_member_workflow"
)

assert mw_api.get_state(profile) == "private"
assert (
    mw_api.get_state(profile, workflow_id="foundation_member_workflow")
    == "active"
)

Next steps#