---
myst:
  html_meta:
    "description": "Load the demo subpackage and apply its profiles to see an additional workflow working end to end."
    "property=og:description": "Load the demo subpackage and apply its profiles to see an additional workflow working end to end."
    "property=og:title": "How to install the worked example"
    "keywords": "Plone, collective.multiworkflow, demo, example, profile"
---

(howto-install-the-demo)=

# 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

- The add-on installed, as described in {doc}`install`.
- The ability to change the ZCML your instance loads.

## 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.

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

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

```xml
<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.

```python
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.

```python
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.

```python
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.

```python
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

- To write your own behavior, see {doc}`declare-additional-workflows`.
- To follow the whole thing from an empty add-on, work through {doc}`/tutorials/add-a-second-workflow`.
