Workflows#
The @workflows service describes the workflows that can be assigned to content types, and changes which workflow the site assigns by default.
It is available at the site root, and requires the Plone Site Setup: Types permission, as well as permission to use the REST API.
Use the Content type management service to change the workflow assignment of a content type, and the Workflow service to change the state of an item.
Method |
Path |
Result |
|---|---|---|
|
|
Every workflow, and the default workflow. |
|
|
One workflow with its states and transitions. |
|
|
Change the default workflow assignment. |
List workflows#
Send a GET request to /@workflows to list every workflow.
http
GET /plone/@workflows HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl
curl -i -X GET http://nohost/plone/@workflows -H "Accept: application/json" --user admin:secret
httpie
http http://nohost/plone/@workflows Accept:application/json -a admin:secret
python-requests
requests.get('http://nohost/plone/@workflows', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
HTTP/1.1 200 OK
Content-Type: application/json
{
"@id": "http://localhost:55001/plone/@workflows",
"default": "simple_publication_workflow",
"items": [
{
"@id": "http://localhost:55001/plone/@workflows/comment_review_workflow",
"description": "A simple review workflow for comments",
"id": "comment_review_workflow",
"initial_state": "pending",
"states": [
"pending",
"published",
"rejected",
"spam"
],
"title": "Comment Review Workflow"
},
{
"@id": "http://localhost:55001/plone/@workflows/plone_workflow",
"description": " - Users can create content that is immediately publicly accessible. - Content can be submitted for publication by the content's creator or a Manager, which is typically done to promote events or news to the front page. - Reviewers can publish or reject content, content owners can retract their submissions. - While the content is awaiting review it is readable by anybody. - If content is published, it can only be retracted by a Manager.",
"id": "plone_workflow",
"initial_state": "visible",
"states": [
"pending",
"private",
"published",
"visible"
],
"title": "Community Workflow"
},
{
"@id": "http://localhost:55001/plone/@workflows/folder_workflow",
"description": " - Used in conjunction with the Community workflow. - Has no pending state. - Allows owner to publish the folder without approval.",
"id": "folder_workflow",
"initial_state": "visible",
"states": [
"private",
"published",
"visible"
],
"title": "Community Workflow for Folders"
},
{
"@id": "http://localhost:55001/plone/@workflows/intranet_folder_workflow",
"description": " - Normally used with the Intranet/Extranet workflow on folder types. - Only has two states: Private and Internal Draft.",
"id": "intranet_folder_workflow",
"initial_state": "internal",
"states": [
"internal",
"private"
],
"title": "Intranet Workflow for Folders"
},
{
"@id": "http://localhost:55001/plone/@workflows/intranet_workflow",
"description": " - An intranet workflow where content is only accessible if you are logged in. - Basic states are: Internal Draft, Pending Review, Internally Published and Private. - Also has an Externally Published state, so you can make selected content available to people outside the intranet.",
"id": "intranet_workflow",
"initial_state": "internal",
"states": [
"internal",
"internally_published",
"pending",
"private",
"external"
],
"title": "Intranet/Extranet Workflow"
},
{
"@id": "http://localhost:55001/plone/@workflows/simple_publication_workflow",
"description": " - Simple workflow that is useful for basic web sites. - Things start out as private, and can either be submitted for review, or published directly. - The creator of a content item can edit the item even after it is published.",
"id": "simple_publication_workflow",
"initial_state": "private",
"states": [
"pending",
"private",
"published"
],
"title": "Simple Publication Workflow"
},
{
"@id": "http://localhost:55001/plone/@workflows/comment_one_state_workflow",
"description": "- Essentially a workflow with no transitions, but has a Published state, so portlets and applications that expect that state will continue to work.",
"id": "comment_one_state_workflow",
"initial_state": "published",
"states": [
"published"
],
"title": "Single State Workflow"
},
{
"@id": "http://localhost:55001/plone/@workflows/one_state_workflow",
"description": "- Essentially a workflow with no transitions, but has a Published state, so portlets and applications that expect that state will continue to work.",
"id": "one_state_workflow",
"initial_state": "published",
"states": [
"published"
],
"title": "Single State Workflow"
}
]
}
The response contains @id, default, and items.
default is the ID of the default workflow, or null when there is none.
The items are sorted by title, and each has these properties:
Property |
Description |
|---|---|
|
URL of the workflow in this service. |
|
Workflow ID. |
|
Translated title. |
|
Translated description. |
|
ID of the state of new items. |
|
IDs of the states, in the order of the workflow. |
Get a workflow#
Send a GET request to /@workflows/{id} to get one workflow with its states and transitions.
Unknown workflows return 404 Not Found.
http
GET /plone/@workflows/simple_publication_workflow HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl
curl -i -X GET http://nohost/plone/@workflows/simple_publication_workflow -H "Accept: application/json" --user admin:secret
httpie
http http://nohost/plone/@workflows/simple_publication_workflow Accept:application/json -a admin:secret
python-requests
requests.get('http://nohost/plone/@workflows/simple_publication_workflow', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
HTTP/1.1 200 OK
Content-Type: application/json
{
"@id": "http://localhost:55001/plone/@workflows/simple_publication_workflow",
"description": " - Simple workflow that is useful for basic web sites. - Things start out as private, and can either be submitted for review, or published directly. - The creator of a content item can edit the item even after it is published.",
"id": "simple_publication_workflow",
"initial_state": "private",
"states": [
{
"description": "Waiting to be reviewed, not editable by the owner.",
"id": "pending",
"permission_roles": {
"Access contents information": [
"Manager",
"Owner",
"Editor",
"Reader",
"Contributor",
"Reviewer",
"Site Administrator"
],
"Modify portal content": [
"Manager",
"Reviewer",
"Site Administrator"
],
"View": [
"Manager",
"Owner",
"Editor",
"Reader",
"Contributor",
"Reviewer",
"Site Administrator"
]
},
"title": "Pending review",
"transitions": [
"publish",
"reject",
"retract"
],
"visibility": "restricted"
},
{
"description": "Can only be seen and edited by the owner.",
"id": "private",
"permission_roles": {
"Access contents information": [
"Manager",
"Owner",
"Editor",
"Reader",
"Contributor",
"Site Administrator"
],
"Modify portal content": [
"Manager",
"Owner",
"Editor",
"Site Administrator"
],
"View": [
"Manager",
"Owner",
"Editor",
"Reader",
"Contributor",
"Site Administrator"
]
},
"title": "Private",
"transitions": [
"publish",
"submit"
],
"visibility": "restricted"
},
{
"description": "Visible to everyone, editable by the owner.",
"id": "published",
"permission_roles": {
"Access contents information": [
"Anonymous"
],
"Modify portal content": [
"Manager",
"Owner",
"Editor",
"Site Administrator"
],
"View": [
"Anonymous"
]
},
"title": "Published with accent \u00e9",
"transitions": [
"retract",
"reject"
],
"visibility": "anyone"
}
],
"title": "Simple Publication Workflow",
"transitions": [
{
"description": "Publishing the item makes it visible to other users.",
"guard": {
"expression": "",
"permissions": [
"Review portal content"
],
"roles": []
},
"id": "publish",
"new_state": "published",
"title": "Publish"
},
{
"description": "Sending the item back will return the item to the original author instead of publishing it. You should preferably include a reason for why it was not published.",
"guard": {
"expression": "",
"permissions": [
"Review portal content"
],
"roles": []
},
"id": "reject",
"new_state": "private",
"title": "Send back"
},
{
"description": "If you submitted the item by mistake or want to perform additional edits, this will take it back.",
"guard": {
"expression": "",
"permissions": [
"Request review"
],
"roles": []
},
"id": "retract",
"new_state": "private",
"title": "Retract"
},
{
"description": "Puts your item in a review queue, so it can be published on the site.",
"guard": {
"expression": "",
"permissions": [
"Request review"
],
"roles": []
},
"id": "submit",
"new_state": "pending",
"title": "Submit for publication"
}
],
"types": [
"ATTestDocument",
"ATTestFolder",
"Collection",
"DXTestDocument",
"Document",
"Event",
"Folder",
"Link",
"News Item",
"TempFolder"
]
}
The response has the properties of the listing, and these:
Property |
Description |
|---|---|
|
The states, each with an |
|
The transitions, each with an |
|
IDs of the content types using the workflow, including those following the default workflow. |
permission_roles maps each permission the state manages to the roles that have it.
visibility summarizes who can see items in the state, from the roles with the View permission:
Value |
Who can see items |
|---|---|
|
Anonymous visitors. |
|
Authenticated users. The roles include |
|
Only the roles listed, such as |
|
The state doesn't manage |
Change the default workflow assignment#
Send a POST request to /@workflows to assign another default workflow.
It affects every content type that follows the default.
The body has these properties:
Property |
Description |
|---|---|
|
ID of the new default workflow, or |
|
Maps the states of the current default workflow to states of the new one. Optional. |
|
When |
Unknown workflows and unknown target states return 400 Bad Request.
Plan the change#
With dry_run, the service returns the number of items in each state, and a suggested new state for each.
http
POST /plone/@workflows HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{
"default": "intranet_workflow",
"dry_run": true
}
curl
curl -i -X POST http://nohost/plone/@workflows -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"default": "intranet_workflow", "dry_run": true}' --user admin:secret
httpie
echo '{
"default": "intranet_workflow",
"dry_run": true
}' | http POST http://nohost/plone/@workflows Accept:application/json Content-Type:application/json -a admin:secret
python-requests
requests.post('http://nohost/plone/@workflows', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'default': 'intranet_workflow', 'dry_run': True}, auth=('admin', 'secret'))
HTTP/1.1 200 OK
Content-Type: application/json
{
"current": "simple_publication_workflow",
"states": [
{
"count": 0,
"id": "pending",
"suggested": "private"
},
{
"count": 1,
"id": "private",
"suggested": "private"
},
{
"count": 1,
"id": "published",
"suggested": "external"
}
],
"types": [
"ATTestDocument",
"ATTestFolder",
"Collection",
"DXTestDocument",
"Document",
"Event",
"Folder",
"Link",
"News Item",
"TempFolder"
],
"unaffected": 0,
"workflow": "intranet_workflow"
}
Property |
Description |
|---|---|
|
ID of the new workflow, or |
|
ID of the current workflow, or |
|
One entry per state of the current workflow, in its order, with the state |
|
Number of items that a placeful workflow policy gives another workflow, which the change doesn't affect. |
|
IDs of the content types following the default workflow. |
Without a current workflow, states has a single entry with an empty id, counting every item of the types.
The counts include items the current user cannot view.
suggested is null when the new workflow is null.
The suggested state keeps who can see the items.
It's the most visible state of the new workflow that isn't more visible than the current state, comparing their visibility (unknown and restricted are the least visible, then members, then anyone).
If every state is more visible, it's the least visible one.
Among equally visible states, the service prefers the one with the same ID, then the one with the same title, then the initial state, then the first state.
Apply the change#
Without dry_run, the service changes the default workflow, moves the items of the types following it to their new states, and updates their security.
States left out of state_map get the suggested state.
The change happens during the request, as in the classic control panel, so it can take long on large sites.
http
POST /plone/@workflows HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{
"default": "intranet_workflow",
"state_map": {
"private": "internal"
}
}
curl
curl -i -X POST http://nohost/plone/@workflows -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"default": "intranet_workflow", "state_map": {"private": "internal"}}' --user admin:secret
httpie
echo '{
"default": "intranet_workflow",
"state_map": {
"private": "internal"
}
}' | http POST http://nohost/plone/@workflows Accept:application/json Content-Type:application/json -a admin:secret
python-requests
requests.post('http://nohost/plone/@workflows', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'default': 'intranet_workflow', 'state_map': {'private': 'internal'}}, auth=('admin', 'secret'))
HTTP/1.1 200 OK
Content-Type: application/json
{
"changed": 2,
"default": "intranet_workflow"
}
The response contains the new default and the number of changed items.