Control Panels#
Control panels in Plone allow you to configure the global site setup of a Plone site.
The @controlpanels
endpoint in plone.restapi
allows you to list all existing control panels in a Plone site, and to retrieve or edit the settings of a specific control panel.
Most of the settings in the Plone control panels are based on plone.registry
since Plone 5.x.
Therefore, you can also use the @registry
endpoint to retrieve or manipulate site settings.
The @controlpanels
endpoint is a more convenient way of accessing the settings, and makes it
easier to render control panels on the front-end.
Note
The @controlpanels
endpoint is implemented for Plone 5 or greater.
Listing Control Panels#
A list of all existing control panels in the portal can be retrieved by sending a GET
request to the @controlpanels
endpoint:
GET /plone/@controlpanels HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl -i -X GET http://nohost/plone/@controlpanels -H "Accept: application/json" --user admin:secret
http http://nohost/plone/@controlpanels Accept:application/json -a admin:secret
requests.get('http://nohost/plone/@controlpanels', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"@id": "http://localhost:55001/plone/@controlpanels/date-and-time",
"group": "General",
"title": "Date and Time"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/language",
"group": "General",
"title": "Language"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/mail",
"group": "General",
"title": "Mail"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/navigation",
"group": "General",
"title": "Navigation"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/search",
"group": "General",
"title": "Search"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/site",
"group": "General",
"title": "Site"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/socialmedia",
"group": "General",
"title": "Social Media"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/content-rules",
"group": "Content",
"title": "Content Rules"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types",
"group": "Content",
"title": "Content Types"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/editing",
"group": "Content",
"title": "Editing"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/imaging",
"group": "Content",
"title": "Image Handling"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/markup",
"group": "Content",
"title": "Markup"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/usergroup",
"group": "Users",
"title": "User and Group Settings"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/security",
"group": "Security",
"title": "Security"
}
]
The following fields are returned:
@id
: hypermedia link to the control paneltitle
: the title of the control panelgroup
: the group in which the control panel should appear, for example,General
,Content
,Users
,Security
,Advanced
, orAdd-on Configuration
.
Retrieve a single Control Panel#
To retrieve a single control panel, send a GET
request to the URL of the control panel:
GET /plone/@controlpanels/editing HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl -i -X GET http://nohost/plone/@controlpanels/editing -H "Accept: application/json" --user admin:secret
http http://nohost/plone/@controlpanels/editing Accept:application/json -a admin:secret
requests.get('http://nohost/plone/@controlpanels/editing', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"@id": "http://localhost:55001/plone/@controlpanels/editing",
"data": {
"available_editors": [
"TinyMCE",
"None"
],
"default_editor": {
"title": "TinyMCE",
"token": "TinyMCE"
},
"enable_link_integrity_checks": true,
"ext_editor": false,
"lock_on_ttw_edit": true,
"subjects_of_navigation_root": false
},
"group": "Content",
"schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"available_editors",
"default_editor",
"ext_editor",
"enable_link_integrity_checks",
"lock_on_ttw_edit",
"subjects_of_navigation_root"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"available_editors": {
"additionalItems": true,
"default": [
"TinyMCE",
"None"
],
"description": "Available editors in the portal.",
"factory": "List",
"items": {
"description": "",
"factory": "Text line (String)",
"title": "",
"type": "string"
},
"title": "Available editors",
"type": "array",
"uniqueItems": false
},
"default_editor": {
"default": "TinyMCE",
"description": "Select the default wysiwyg editor. Users will be able to choose their own or select to use the site default.",
"factory": "Choice",
"title": "Default editor",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.AvailableEditors"
}
},
"enable_link_integrity_checks": {
"default": true,
"description": "Determines if the users should get warnings when they delete or move content that is linked from inside the site.",
"factory": "Yes/No",
"title": "Enable link integrity checks",
"type": "boolean"
},
"ext_editor": {
"default": false,
"description": "Determines if the external editor feature is enabled. This feature requires a special client-side application installed. The users also have to enable this in their preferences.",
"factory": "Yes/No",
"title": "Enable External Editor feature",
"type": "boolean"
},
"lock_on_ttw_edit": {
"default": true,
"description": "Disabling locking here will only affect users editing content through the Plone web UI. Content edited via WebDAV clients will still be subject to locking.",
"factory": "Yes/No",
"title": "Enable locking for through-the-web edits",
"type": "boolean"
},
"subjects_of_navigation_root": {
"default": false,
"description": "Limit tags aka keywords vocabulary used for Tags field and in searches to the terms used inside the subtree of the current navigation root. This can be used together with Plone's multilingual extension plone.app.multilingual to only offer keywords of the current selected language. Other addons may utilize this feature for its specific purposes.",
"factory": "Yes/No",
"title": "Limit tags/keywords to the current navigation root",
"type": "boolean"
}
},
"required": [
"available_editors",
"default_editor"
],
"type": "object"
},
"title": "Editing"
}
The following fields are returned:
@id
: hypermedia link to the control paneltitle
: title of the control panelgroup
: group name of the control panelschema
: JSON Schema of the control paneldata
: current values of the control panel
Updating a Control Panel with PATCH
#
To update the settings on a control panel, send a PATCH
request to control panel resource:
PATCH /plone/@controlpanels/editing HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{
"default_editor": "CKeditor",
"ext_editor": true
}
curl -i -X PATCH http://nohost/plone/@controlpanels/editing -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"default_editor": "CKeditor", "ext_editor": true}' --user admin:secret
echo '{
"default_editor": "CKeditor",
"ext_editor": true
}' | http PATCH http://nohost/plone/@controlpanels/editing Accept:application/json Content-Type:application/json -a admin:secret
requests.patch('http://nohost/plone/@controlpanels/editing', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'default_editor': 'CKeditor', 'ext_editor': True}, auth=('admin', 'secret'))
A successful response to a PATCH
request will be indicated by a 204 No Content response:
HTTP/1.1 204 No Content
Control Panels not based on plone.registry
#
Control panels which are not based on plone.registry
have a custom @controlpanels/:panel
endpoint implementation.
Dexterity Types#
@controlpanels/dexterity-types
is a custom control panel endpoint that will allow you to add, remove, and configure available Types.
Reading or writing Dexterity content types require the plone.schemaeditor.ManageSchemata
permission.
Verb |
URL |
Action |
---|---|---|
|
|
List configurable content types |
|
|
Creates a new content type |
|
|
Get the current state of the content type |
|
|
Update the content type details |
|
|
Remove the content type |
Listing Dexterity Content Types#
To list the available content types, send a GET
request to @controlpanels/dexterity-types
GET /plone/@controlpanels/dexterity-types HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl -i -X GET http://nohost/plone/@controlpanels/dexterity-types -H "Accept: application/json" --user admin:secret
http http://nohost/plone/@controlpanels/dexterity-types Accept:application/json -a admin:secret
requests.get('http://nohost/plone/@controlpanels/dexterity-types', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types",
"data": {},
"group": "Content",
"items": [
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/Plone Site",
"@type": "Plone Site",
"count": 1,
"description": "",
"id": "Plone Site",
"meta_type": "Dexterity FTI",
"title": "Plone Site"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/Collection",
"@type": "Collection",
"count": 0,
"description": "",
"id": "Collection",
"meta_type": "Dexterity FTI",
"title": "Collection"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/Document",
"@type": "Document",
"count": 0,
"description": "",
"id": "Document",
"meta_type": "Dexterity FTI",
"title": "Page"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/Folder",
"@type": "Folder",
"count": 0,
"description": "",
"id": "Folder",
"meta_type": "Dexterity FTI",
"title": "Folder"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/Link",
"@type": "Link",
"count": 0,
"description": "",
"id": "Link",
"meta_type": "Dexterity FTI",
"title": "Link"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/File",
"@type": "File",
"count": 0,
"description": "Lets you upload a file to the site.",
"id": "File",
"meta_type": "Dexterity FTI",
"title": "File"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/Image",
"@type": "Image",
"count": 0,
"description": "Images can be referenced in pages or displayed in an album.",
"id": "Image",
"meta_type": "Dexterity FTI",
"title": "Image"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/News Item",
"@type": "News Item",
"count": 0,
"description": "",
"id": "News Item",
"meta_type": "Dexterity FTI",
"title": "News Item"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/Event",
"@type": "Event",
"count": 0,
"description": "Events can be shown in calendars.",
"id": "Event",
"meta_type": "Dexterity FTI",
"title": "Event"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/DXTestDocument",
"@type": "DXTestDocument",
"count": 0,
"description": "",
"id": "DXTestDocument",
"meta_type": "Dexterity FTI",
"title": "DX Test Document"
}
],
"schema": {
"fieldsets": [],
"properties": {},
"required": [],
"type": "object"
},
"title": "Content Types"
}
The following fields are returned:
@id
: hypermedia link to the control paneltitle
: title of the control panelgroup
: group name of the control panelschema
: JSON Schema of the control paneldata
: current values of the control panelitems
: list of configurable content types
Creating a new Dexterity Type with POST
#
To create a new content type, send a POST
request to the /@controlpanels/dexterity-types
endpoint:
POST /plone/@controlpanels/dexterity-types HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{
"description": "A custom content-type",
"title": "My Custom Content Type"
}
curl -i -X POST http://nohost/plone/@controlpanels/dexterity-types -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"description": "A custom content-type", "title": "My Custom Content Type"}' --user admin:secret
echo '{
"description": "A custom content-type",
"title": "My Custom Content Type"
}' | http POST http://nohost/plone/@controlpanels/dexterity-types Accept:application/json Content-Type:application/json -a admin:secret
requests.post('http://nohost/plone/@controlpanels/dexterity-types', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'description': 'A custom content-type', 'title': 'My Custom Content Type'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 201 Created
Content-Type: application/json
Location: http://localhost:55001/plone/@controlpanels/dexterity-types/my_custom_content_type
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/my_custom_content_type",
"data": {
"allowed_content_types": [],
"description": "A custom content-type",
"filter_content_types": true,
"plone.allowdiscussion": false,
"plone.basic": false,
"plone.categorization": false,
"plone.collection": false,
"plone.constraintypes": false,
"plone.dublincore": true,
"plone.eventattendees": false,
"plone.eventbasic": false,
"plone.eventcontact": false,
"plone.eventlocation": false,
"plone.eventrecurrence": false,
"plone.excludefromnavigation": false,
"plone.leadimage": false,
"plone.locking": false,
"plone.namefromfilename": false,
"plone.namefromtitle": true,
"plone.navigationroot": false,
"plone.nextpreviousenabled": false,
"plone.nextprevioustoggle": false,
"plone.ownership": false,
"plone.publication": false,
"plone.relateditems": false,
"plone.richtext": false,
"plone.shortname": false,
"plone.tableofcontents": false,
"plone.textindexer": false,
"plone.thumb_icon": false,
"plone.translatable": false,
"plone.versioning": false,
"tests.restapi.test_annotations_behavior": false,
"tests.restapi.test_behavior": false,
"title": "My Custom Content Type",
"volto.blocks": false,
"volto.blocks.editable.layout": false
},
"description": "A custom content-type",
"group": "Content",
"items": [],
"schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"title",
"description",
"allowed_content_types",
"filter_content_types"
],
"id": "default",
"title": "Default"
},
{
"behavior": "plone",
"fields": [
"plone.allowdiscussion",
"plone.basic",
"volto.blocks",
"volto.blocks.editable.layout",
"plone.categorization",
"plone.collection",
"plone.publication",
"plone.dublincore",
"plone.eventattendees",
"plone.eventbasic",
"plone.eventcontact",
"plone.eventlocation",
"plone.eventrecurrence",
"plone.excludefromnavigation",
"plone.constraintypes",
"plone.textindexer",
"plone.leadimage",
"plone.locking",
"plone.translatable",
"plone.namefromfilename",
"plone.namefromtitle",
"plone.navigationroot",
"plone.nextpreviousenabled",
"plone.nextprevioustoggle",
"plone.ownership",
"plone.relateditems",
"plone.richtext",
"plone.shortname",
"plone.tableofcontents",
"tests.restapi.test_annotations_behavior",
"tests.restapi.test_behavior",
"plone.thumb_icon",
"plone.versioning"
],
"id": "behaviors",
"title": "Behaviors"
}
],
"properties": {
"allowed_content_types": {
"additionalItems": true,
"description": "",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.ReallyUserFriendlyTypes"
}
},
"title": "Allowed Content Types",
"type": "array",
"uniqueItems": true
},
"description": {
"description": "",
"factory": "Text",
"title": "Description",
"type": "string",
"widget": "textarea"
},
"filter_content_types": {
"choices": [
[
"none",
null
],
[
"all",
null
],
[
"some",
null
]
],
"default": "none",
"description": "Items of this type can act as a folder containing other items. What content types should be allowed inside?",
"enum": [
"none",
"all",
"some"
],
"enumNames": [
null,
null,
null
],
"factory": "Choice",
"title": "Filter Contained Types",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/filter_content_types"
}
},
"plone.allowdiscussion": {
"description": "Allow discussion on this item",
"factory": "Yes/No",
"title": "Allow discussion",
"type": "boolean"
},
"plone.basic": {
"description": "Adds title and description fields.",
"factory": "Yes/No",
"title": "Basic metadata",
"type": "boolean"
},
"plone.categorization": {
"description": "Adds keywords and language fields.",
"factory": "Yes/No",
"title": "Categorization",
"type": "boolean"
},
"plone.collection": {
"description": "Adds collection behavior",
"factory": "Yes/No",
"title": "Collection",
"type": "boolean"
},
"plone.constraintypes": {
"description": "Restrict the content types that can be added to folderish content",
"factory": "Yes/No",
"title": "Folder Addable Constrains",
"type": "boolean"
},
"plone.dublincore": {
"description": "Adds standard metadata fields (equals Basic metadata + Categorization + Effective range + Ownership)",
"factory": "Yes/No",
"title": "Dublin Core metadata",
"type": "boolean"
},
"plone.eventattendees": {
"description": "Attendees extension for Events.",
"factory": "Yes/No",
"title": "Event Attendees",
"type": "boolean"
},
"plone.eventbasic": {
"description": "Basic Event schema.",
"factory": "Yes/No",
"title": "Event Basic",
"type": "boolean"
},
"plone.eventcontact": {
"description": "Contact extension for Events.",
"factory": "Yes/No",
"title": "Event Contact",
"type": "boolean"
},
"plone.eventlocation": {
"description": "Location extension for Events.",
"factory": "Yes/No",
"title": "Event Location",
"type": "boolean"
},
"plone.eventrecurrence": {
"description": "Recurrence extension for Events.",
"factory": "Yes/No",
"title": "Event Recurrence",
"type": "boolean"
},
"plone.excludefromnavigation": {
"description": "Allow items to be excluded from navigation",
"factory": "Yes/No",
"title": "Exclude From navigation",
"type": "boolean"
},
"plone.leadimage": {
"description": "Adds image and image caption fields",
"factory": "Yes/No",
"title": "Lead Image",
"type": "boolean"
},
"plone.locking": {
"description": "Locking support for dexterity",
"factory": "Yes/No",
"title": "Locking",
"type": "boolean"
},
"plone.namefromfilename": {
"description": "Automatically generate short URL name for content based on its primary field file name",
"factory": "Yes/No",
"title": "Name from file name",
"type": "boolean"
},
"plone.namefromtitle": {
"description": "Automatically generate short URL name for content based on its initial title",
"factory": "Yes/No",
"title": "Name from title",
"type": "boolean"
},
"plone.navigationroot": {
"description": "Make all items of this type a navigation root",
"factory": "Yes/No",
"title": "Navigation root",
"type": "boolean"
},
"plone.nextpreviousenabled": {
"description": "Enable next previous navigation for all items of this type",
"factory": "Yes/No",
"title": "Next previous navigation",
"type": "boolean"
},
"plone.nextprevioustoggle": {
"description": "Allow items to have next previous navigation enabled",
"factory": "Yes/No",
"title": "Next previous navigation toggle",
"type": "boolean"
},
"plone.ownership": {
"description": "Adds creator, contributor, and rights fields.",
"factory": "Yes/No",
"title": "Ownership",
"type": "boolean"
},
"plone.publication": {
"description": "Adds effective date and expiration date fields.",
"factory": "Yes/No",
"title": "Date range",
"type": "boolean"
},
"plone.relateditems": {
"description": "Adds the ability to assign related items",
"factory": "Yes/No",
"title": "Related items",
"type": "boolean"
},
"plone.richtext": {
"description": "Adds richtext behavior",
"factory": "Yes/No",
"title": "RichText",
"type": "boolean"
},
"plone.shortname": {
"description": "Gives the ability to rename an item from its edit form.",
"factory": "Yes/No",
"title": "Short name",
"type": "boolean"
},
"plone.tableofcontents": {
"description": "Adds a table of contents",
"factory": "Yes/No",
"title": "Table of contents",
"type": "boolean"
},
"plone.textindexer": {
"description": "Enables the enhanced full-text indexing for a content type ('plone.textindexer'). If a field is marked 'searchable', its content gets added to the 'SearchableText' index in the catalog.",
"factory": "Yes/No",
"title": "Full-Text Indexing",
"type": "boolean"
},
"plone.thumb_icon": {
"description": "Options to suppress thumbs and/or icons and to override thumb size in listings, tables etc.",
"factory": "Yes/No",
"title": "Thumbs and icon handling",
"type": "boolean"
},
"plone.translatable": {
"description": "Make this content type multilingual aware",
"factory": "Yes/No",
"title": "Multilingual Support",
"type": "boolean"
},
"plone.versioning": {
"description": "Versioning support with CMFEditions",
"factory": "Yes/No",
"title": "Versioning",
"type": "boolean"
},
"tests.restapi.test_annotations_behavior": {
"description": "Schema-only behavior using annotations",
"factory": "Yes/No",
"title": "Test Annotations Behavior",
"type": "boolean"
},
"tests.restapi.test_behavior": {
"description": "Schema-only behavior using attributes",
"factory": "Yes/No",
"title": "Test Behavior",
"type": "boolean"
},
"title": {
"description": "",
"factory": "Text line (String)",
"title": "Type Name",
"type": "string"
},
"volto.blocks": {
"description": "Enables Volto Blocks support",
"factory": "Yes/No",
"title": "Blocks",
"type": "boolean"
},
"volto.blocks.editable.layout": {
"description": "Enables Volto Blocks (editable layout) support",
"factory": "Yes/No",
"title": "Blocks (Editable Layout)",
"type": "boolean"
}
},
"required": [
"title",
"filter_content_types"
],
"type": "object"
},
"title": "My Custom Content Type"
}
Reading a Dexterity Type with GET
#
After a successful POST
, access the content type by sending a GET
request to the endpoint /@controlpanels/dexterity-types/{type-id}
:
GET /plone/@controlpanels/dexterity-types/my_custom_content_type HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl -i -X GET http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type -H "Accept: application/json" --user admin:secret
http http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type Accept:application/json -a admin:secret
requests.get('http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"@id": "http://localhost:55001/plone/@controlpanels/dexterity-types/my_custom_content_type",
"data": {
"allowed_content_types": [],
"description": "A custom content-type",
"filter_content_types": true,
"plone.allowdiscussion": false,
"plone.basic": false,
"plone.categorization": false,
"plone.collection": false,
"plone.constraintypes": false,
"plone.dublincore": true,
"plone.eventattendees": false,
"plone.eventbasic": false,
"plone.eventcontact": false,
"plone.eventlocation": false,
"plone.eventrecurrence": false,
"plone.excludefromnavigation": false,
"plone.leadimage": false,
"plone.locking": false,
"plone.namefromfilename": false,
"plone.namefromtitle": true,
"plone.navigationroot": false,
"plone.nextpreviousenabled": false,
"plone.nextprevioustoggle": false,
"plone.ownership": false,
"plone.publication": false,
"plone.relateditems": false,
"plone.richtext": false,
"plone.shortname": false,
"plone.tableofcontents": false,
"plone.textindexer": false,
"plone.thumb_icon": false,
"plone.translatable": false,
"plone.versioning": false,
"tests.restapi.test_annotations_behavior": false,
"tests.restapi.test_behavior": false,
"title": "My Custom Content Type",
"volto.blocks": false,
"volto.blocks.editable.layout": false
},
"description": "A custom content-type",
"group": "Content",
"items": [],
"schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"title",
"description",
"allowed_content_types",
"filter_content_types"
],
"id": "default",
"title": "Default"
},
{
"behavior": "plone",
"fields": [
"plone.allowdiscussion",
"plone.basic",
"volto.blocks",
"volto.blocks.editable.layout",
"plone.categorization",
"plone.collection",
"plone.publication",
"plone.dublincore",
"plone.eventattendees",
"plone.eventbasic",
"plone.eventcontact",
"plone.eventlocation",
"plone.eventrecurrence",
"plone.excludefromnavigation",
"plone.constraintypes",
"plone.textindexer",
"plone.leadimage",
"plone.locking",
"plone.translatable",
"plone.namefromfilename",
"plone.namefromtitle",
"plone.navigationroot",
"plone.nextpreviousenabled",
"plone.nextprevioustoggle",
"plone.ownership",
"plone.relateditems",
"plone.richtext",
"plone.shortname",
"plone.tableofcontents",
"tests.restapi.test_annotations_behavior",
"tests.restapi.test_behavior",
"plone.thumb_icon",
"plone.versioning"
],
"id": "behaviors",
"title": "Behaviors"
}
],
"properties": {
"allowed_content_types": {
"additionalItems": true,
"description": "",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.ReallyUserFriendlyTypes"
}
},
"title": "Allowed Content Types",
"type": "array",
"uniqueItems": true
},
"description": {
"description": "",
"factory": "Text",
"title": "Description",
"type": "string",
"widget": "textarea"
},
"filter_content_types": {
"choices": [
[
"none",
null
],
[
"all",
null
],
[
"some",
null
]
],
"default": "none",
"description": "Items of this type can act as a folder containing other items. What content types should be allowed inside?",
"enum": [
"none",
"all",
"some"
],
"enumNames": [
null,
null,
null
],
"factory": "Choice",
"title": "Filter Contained Types",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/filter_content_types"
}
},
"plone.allowdiscussion": {
"description": "Allow discussion on this item",
"factory": "Yes/No",
"title": "Allow discussion",
"type": "boolean"
},
"plone.basic": {
"description": "Adds title and description fields.",
"factory": "Yes/No",
"title": "Basic metadata",
"type": "boolean"
},
"plone.categorization": {
"description": "Adds keywords and language fields.",
"factory": "Yes/No",
"title": "Categorization",
"type": "boolean"
},
"plone.collection": {
"description": "Adds collection behavior",
"factory": "Yes/No",
"title": "Collection",
"type": "boolean"
},
"plone.constraintypes": {
"description": "Restrict the content types that can be added to folderish content",
"factory": "Yes/No",
"title": "Folder Addable Constrains",
"type": "boolean"
},
"plone.dublincore": {
"description": "Adds standard metadata fields (equals Basic metadata + Categorization + Effective range + Ownership)",
"factory": "Yes/No",
"title": "Dublin Core metadata",
"type": "boolean"
},
"plone.eventattendees": {
"description": "Attendees extension for Events.",
"factory": "Yes/No",
"title": "Event Attendees",
"type": "boolean"
},
"plone.eventbasic": {
"description": "Basic Event schema.",
"factory": "Yes/No",
"title": "Event Basic",
"type": "boolean"
},
"plone.eventcontact": {
"description": "Contact extension for Events.",
"factory": "Yes/No",
"title": "Event Contact",
"type": "boolean"
},
"plone.eventlocation": {
"description": "Location extension for Events.",
"factory": "Yes/No",
"title": "Event Location",
"type": "boolean"
},
"plone.eventrecurrence": {
"description": "Recurrence extension for Events.",
"factory": "Yes/No",
"title": "Event Recurrence",
"type": "boolean"
},
"plone.excludefromnavigation": {
"description": "Allow items to be excluded from navigation",
"factory": "Yes/No",
"title": "Exclude From navigation",
"type": "boolean"
},
"plone.leadimage": {
"description": "Adds image and image caption fields",
"factory": "Yes/No",
"title": "Lead Image",
"type": "boolean"
},
"plone.locking": {
"description": "Locking support for dexterity",
"factory": "Yes/No",
"title": "Locking",
"type": "boolean"
},
"plone.namefromfilename": {
"description": "Automatically generate short URL name for content based on its primary field file name",
"factory": "Yes/No",
"title": "Name from file name",
"type": "boolean"
},
"plone.namefromtitle": {
"description": "Automatically generate short URL name for content based on its initial title",
"factory": "Yes/No",
"title": "Name from title",
"type": "boolean"
},
"plone.navigationroot": {
"description": "Make all items of this type a navigation root",
"factory": "Yes/No",
"title": "Navigation root",
"type": "boolean"
},
"plone.nextpreviousenabled": {
"description": "Enable next previous navigation for all items of this type",
"factory": "Yes/No",
"title": "Next previous navigation",
"type": "boolean"
},
"plone.nextprevioustoggle": {
"description": "Allow items to have next previous navigation enabled",
"factory": "Yes/No",
"title": "Next previous navigation toggle",
"type": "boolean"
},
"plone.ownership": {
"description": "Adds creator, contributor, and rights fields.",
"factory": "Yes/No",
"title": "Ownership",
"type": "boolean"
},
"plone.publication": {
"description": "Adds effective date and expiration date fields.",
"factory": "Yes/No",
"title": "Date range",
"type": "boolean"
},
"plone.relateditems": {
"description": "Adds the ability to assign related items",
"factory": "Yes/No",
"title": "Related items",
"type": "boolean"
},
"plone.richtext": {
"description": "Adds richtext behavior",
"factory": "Yes/No",
"title": "RichText",
"type": "boolean"
},
"plone.shortname": {
"description": "Gives the ability to rename an item from its edit form.",
"factory": "Yes/No",
"title": "Short name",
"type": "boolean"
},
"plone.tableofcontents": {
"description": "Adds a table of contents",
"factory": "Yes/No",
"title": "Table of contents",
"type": "boolean"
},
"plone.textindexer": {
"description": "Enables the enhanced full-text indexing for a content type ('plone.textindexer'). If a field is marked 'searchable', its content gets added to the 'SearchableText' index in the catalog.",
"factory": "Yes/No",
"title": "Full-Text Indexing",
"type": "boolean"
},
"plone.thumb_icon": {
"description": "Options to suppress thumbs and/or icons and to override thumb size in listings, tables etc.",
"factory": "Yes/No",
"title": "Thumbs and icon handling",
"type": "boolean"
},
"plone.translatable": {
"description": "Make this content type multilingual aware",
"factory": "Yes/No",
"title": "Multilingual Support",
"type": "boolean"
},
"plone.versioning": {
"description": "Versioning support with CMFEditions",
"factory": "Yes/No",
"title": "Versioning",
"type": "boolean"
},
"tests.restapi.test_annotations_behavior": {
"description": "Schema-only behavior using annotations",
"factory": "Yes/No",
"title": "Test Annotations Behavior",
"type": "boolean"
},
"tests.restapi.test_behavior": {
"description": "Schema-only behavior using attributes",
"factory": "Yes/No",
"title": "Test Behavior",
"type": "boolean"
},
"title": {
"description": "",
"factory": "Text line (String)",
"title": "Type Name",
"type": "string"
},
"volto.blocks": {
"description": "Enables Volto Blocks support",
"factory": "Yes/No",
"title": "Blocks",
"type": "boolean"
},
"volto.blocks.editable.layout": {
"description": "Enables Volto Blocks (editable layout) support",
"factory": "Yes/No",
"title": "Blocks (Editable Layout)",
"type": "boolean"
}
},
"required": [
"title",
"filter_content_types"
],
"type": "object"
},
"title": "My Custom Content Type"
}
Updating a Dexterity Type with PATCH
#
To update an existing content type, send a PATCH
request to the server.
PATCH
allows to provide just a subset of the resource, that is, the values you actually want to change:
PATCH /plone/@controlpanels/dexterity-types/my_custom_content_type HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{
"description": "A content-type",
"plone.richtext": true,
"plone.versioning": true,
"title": "My Content Type"
}
curl -i -X PATCH http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"description": "A content-type", "plone.richtext": true, "plone.versioning": true, "title": "My Content Type"}' --user admin:secret
echo '{
"description": "A content-type",
"plone.richtext": true,
"plone.versioning": true,
"title": "My Content Type"
}' | http PATCH http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type Accept:application/json Content-Type:application/json -a admin:secret
requests.patch('http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'description': 'A content-type', 'plone.richtext': True, 'plone.versioning': True, 'title': 'My Content Type'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 204 No Content
Removing a Dexterity Type with DELETE
#
Delete an existing content type by sending a DELETE
request to the URL of an existing content type:
DELETE /plone/@controlpanels/dexterity-types/my_custom_content_type HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl -i -X DELETE http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type -H "Accept: application/json" --user admin:secret
http DELETE http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type Accept:application/json -a admin:secret
requests.delete('http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 204 No Content
Content rules#
@controlpanels/content-rules
is a custom control panel endpoint that will allow you to add, remove, and configure available Content Rules.
Verb |
URL |
Action |
---|---|---|
|
|
List configurable content rules |
|
|
Creates a new content rule |
|
|
Get the current state of the content rule |
|
|
Update the content rule details |
|
|
Remove the content rule |
Listing Content Rules#
To list the available content rules, send a GET
request to @controlpanels/content-rules
GET /plone/@controlpanels/content-rules HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl -i -X GET http://nohost/plone/@controlpanels/content-rules -H "Accept: application/json" --user admin:secret
http http://nohost/plone/@controlpanels/content-rules Accept:application/json -a admin:secret
requests.get('http://nohost/plone/@controlpanels/content-rules', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"@id": "http://localhost:55001/plone/@controlpanels/content-rules",
"data": {},
"group": "Content",
"items": [
[
{
"@id": "http://localhost:55001/plone/@controlpanels/content-rules/rule-1",
"assigned": true,
"description": "First rule added in the testing setup",
"enabled": true,
"id": "rule-1",
"row_class": "trigger-icommentaddedevent state-enabled assignment-assigned",
"title": "First test rule",
"trigger": "Comment added"
},
{
"@id": "http://localhost:55001/plone/@controlpanels/content-rules/rule-2",
"assigned": true,
"description": "Second rule added in the testing setup",
"enabled": true,
"id": "rule-2",
"row_class": "trigger-icommentaddedevent state-enabled assignment-assigned",
"title": "Second test rule",
"trigger": "Comment added"
}
]
],
"schema": {
"fieldsets": [],
"properties": {},
"required": [],
"type": "object"
},
"title": "Content Rules"
}
The following fields are returned:
@id
: hypermedia link to the ruleid
: actual id of the content ruleassigned
: rule assigned or nottitle
: title of the ruledescription
: rule descriptionenabled
: rule is enabled or nottrigger
: triggering eventconditions
: conditions before triggering the ruleactions
: actions to take place
Creating a new Content rule with POST
#
To create a new content rule, send a POST
request to the /@controlpanels/content-rules
endpoint:
POST /plone/@controlpanels/content-rules HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{
"cascading": false,
"description": "Third rule added in the testing setup",
"enabled": true,
"event": "Comment added",
"stop": false,
"title": "Third test rule"
}
curl -i -X POST http://nohost/plone/@controlpanels/content-rules -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"cascading": false, "description": "Third rule added in the testing setup", "enabled": true, "event": "Comment added", "stop": false, "title": "Third test rule"}' --user admin:secret
echo '{
"cascading": false,
"description": "Third rule added in the testing setup",
"enabled": true,
"event": "Comment added",
"stop": false,
"title": "Third test rule"
}' | http POST http://nohost/plone/@controlpanels/content-rules Accept:application/json Content-Type:application/json -a admin:secret
requests.post('http://nohost/plone/@controlpanels/content-rules', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'cascading': False, 'description': 'Third rule added in the testing setup', 'enabled': True, 'event': 'Comment added', 'stop': False, 'title': 'Third test rule'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 201 Created
Content-Type: application/json
Location: http://localhost:55001/plone/@controlpanels/content-rules/rule-3
{
"@id": "http://localhost:55001/plone/@controlpanels/content-rules/rule-3",
"actions": [],
"addable_actions": [
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"targetLogger",
"loggingLevel",
"message"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"loggingLevel": {
"default": 20,
"description": "",
"factory": "Integer",
"title": "Logging level",
"type": "integer"
},
"message": {
"default": "text_contentrules_logger_message",
"description": "&e = the triggering event, &c = the context, &u = the user",
"factory": "Text line (String)",
"title": "Message",
"type": "string"
},
"targetLogger": {
"default": "Plone",
"description": "",
"factory": "Text line (String)",
"title": "Logger name",
"type": "string"
}
},
"required": [
"targetLogger",
"loggingLevel",
"message"
],
"type": "object"
},
"addview": "plone.actions.Logger",
"description": "Log a particular event",
"title": "Logger"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"message",
"message_type"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"message": {
"description": "The message to send to the user.",
"factory": "Text line (String)",
"title": "Message",
"type": "string"
},
"message_type": {
"choices": [
[
"info",
null
],
[
"warning",
null
],
[
"error",
null
]
],
"default": "info",
"description": "Select the type of message to display.",
"enum": [
"info",
"warning",
"error"
],
"enumNames": [
null,
null,
null
],
"factory": "Choice",
"title": "Message type",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/message_type"
}
}
},
"required": [
"message",
"message_type"
],
"type": "object"
},
"addview": "plone.actions.Notify",
"description": "Return a portal message to the user",
"title": "Notify user"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"target_folder"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"target_folder": {
"description": "As a path relative to the portal root.",
"factory": "Choice",
"title": "Target folder",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/target_folder"
}
}
},
"required": [
"target_folder"
],
"type": "object"
},
"addview": "plone.actions.Copy",
"description": "Copy the triggering item to a specific folder",
"title": "Copy to folder"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"target_folder"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"target_folder": {
"description": "As a path relative to the portal root.",
"factory": "Choice",
"title": "Target folder",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/target_folder"
}
}
},
"required": [
"target_folder"
],
"type": "object"
},
"addview": "plone.actions.Move",
"description": "Move the triggering item to a specific folder",
"title": "Move to folder"
},
{
"@schema": {
"fieldsets": [],
"properties": {},
"required": [],
"type": "object"
},
"addview": "plone.actions.Delete",
"description": "Delete the triggering item",
"title": "Delete object"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"transition"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"transition": {
"description": "Select the workflow transition to attempt",
"factory": "Choice",
"title": "Transition",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.WorkflowTransitions"
}
}
},
"required": [
"transition"
],
"type": "object"
},
"addview": "plone.actions.Workflow",
"description": "Perform a workflow transition on the triggering object",
"title": "Transition workflow state"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"subject",
"source",
"recipients",
"exclude_actor",
"message"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"exclude_actor": {
"description": "Do not send the email to the user that did the action.",
"factory": "Yes/No",
"title": "Exclude actor from recipients",
"type": "boolean"
},
"message": {
"description": "The message that you want to mail.",
"factory": "Text",
"title": "Message",
"type": "string",
"widget": "textarea"
},
"recipients": {
"description": "The email where you want to send this message. To send it to different email addresses, just separate them with ,",
"factory": "Text line (String)",
"title": "Email recipients",
"type": "string"
},
"source": {
"description": "The email address that sends the email. If no email is provided here, it will use the portal from address.",
"factory": "Text line (String)",
"title": "Email source",
"type": "string"
},
"subject": {
"description": "Subject of the message",
"factory": "Text line (String)",
"title": "Subject",
"type": "string"
}
},
"required": [
"subject",
"recipients",
"message"
],
"type": "object"
},
"addview": "plone.actions.Mail",
"description": "Send an email on the triggering object",
"title": "Send email"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"comment"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"comment": {
"description": "The comment added to the history while versioning the content.",
"factory": "Text line (String)",
"title": "Comment",
"type": "string"
}
},
"required": [],
"type": "object"
},
"addview": "plone.actions.Versioning",
"description": "Store a new version of the object",
"title": "Version object"
}
],
"addable_conditions": [
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"check_types"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"check_types": {
"additionalItems": true,
"description": "The content type to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.ReallyUserFriendlyTypes"
}
},
"title": "Content type",
"type": "array",
"uniqueItems": true
}
},
"required": [
"check_types"
],
"type": "object"
},
"addview": "plone.conditions.PortalType",
"description": "Apply only when the current content object is of a particular type",
"title": "Content type"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"file_extension"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"file_extension": {
"description": "The file extension to check for",
"factory": "Text line (String)",
"title": "File extension",
"type": "string"
}
},
"required": [
"file_extension"
],
"type": "object"
},
"addview": "plone.conditions.FileExtension",
"description": "Apply only to a particular file extension",
"title": "File Extension"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"wf_states"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"wf_states": {
"additionalItems": true,
"description": "The workflow states to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.WorkflowStates"
}
},
"title": "Workflow state",
"type": "array",
"uniqueItems": true
}
},
"required": [
"wf_states"
],
"type": "object"
},
"addview": "plone.conditions.WorkflowState",
"description": "Apply only to a objects in a particular workflow state",
"title": "Workflow state"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"group_names"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"group_names": {
"additionalItems": true,
"description": "The name of the group.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Groups"
}
},
"title": "Group name",
"type": "array",
"uniqueItems": true
}
},
"required": [
"group_names"
],
"type": "object"
},
"addview": "plone.conditions.Group",
"description": "Apply only when the current user is in the given group",
"title": "User's group"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"role_names"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"role_names": {
"additionalItems": true,
"description": "The roles to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Roles"
}
},
"title": "Roles",
"type": "array",
"uniqueItems": true
}
},
"required": [
"role_names"
],
"type": "object"
},
"addview": "plone.conditions.Role",
"description": "Apply only when the current user has the given role",
"title": "User's role"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"tales_expression"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"tales_expression": {
"description": "The TALES expression to check.",
"factory": "Text line (String)",
"title": "TALES expression",
"type": "string"
}
},
"required": [
"tales_expression"
],
"type": "object"
},
"addview": "plone.conditions.TalesExpression",
"description": "Apply only when the result of a TALES expression is True",
"title": "TALES expression"
}
],
"assignments": [],
"cascading": false,
"conditions": [],
"description": "Third rule added in the testing setup",
"enabled": true,
"event": "Comment added",
"group": "Content",
"id": "rule-3",
"stop": false,
"title": "Third test rule"
}
Creating a new Condition on a Content rule with POST
#
To create a new condition on a content rule, send a POST
request to the
/@controlpanels/content-rules/{rule-id}/condition
endpoint, specifying the
condition type in the payload:
POST /plone/@controlpanels/content-rules/rule-3/condition HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{
"check_types": [
"Collection",
"Comment"
],
"type": "plone.conditions.PortalType"
}
curl -i -X POST http://nohost/plone/@controlpanels/content-rules/rule-3/condition -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"check_types": ["Collection", "Comment"], "type": "plone.conditions.PortalType"}' --user admin:secret
echo '{
"check_types": [
"Collection",
"Comment"
],
"type": "plone.conditions.PortalType"
}' | http POST http://nohost/plone/@controlpanels/content-rules/rule-3/condition Accept:application/json Content-Type:application/json -a admin:secret
requests.post('http://nohost/plone/@controlpanels/content-rules/rule-3/condition', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'check_types': ['Collection', 'Comment'], 'type': 'plone.conditions.PortalType'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 201 Created
Content-Type: application/json
Location: http://localhost:55001/plone/@controlpanels/content-rules/rule-3
{
"@id": "http://localhost:55001/plone/@controlpanels/content-rules/rule-3",
"actions": [],
"addable_actions": [
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"targetLogger",
"loggingLevel",
"message"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"loggingLevel": {
"default": 20,
"description": "",
"factory": "Integer",
"title": "Logging level",
"type": "integer"
},
"message": {
"default": "text_contentrules_logger_message",
"description": "&e = the triggering event, &c = the context, &u = the user",
"factory": "Text line (String)",
"title": "Message",
"type": "string"
},
"targetLogger": {
"default": "Plone",
"description": "",
"factory": "Text line (String)",
"title": "Logger name",
"type": "string"
}
},
"required": [
"targetLogger",
"loggingLevel",
"message"
],
"type": "object"
},
"addview": "plone.actions.Logger",
"description": "Log a particular event",
"title": "Logger"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"message",
"message_type"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"message": {
"description": "The message to send to the user.",
"factory": "Text line (String)",
"title": "Message",
"type": "string"
},
"message_type": {
"choices": [
[
"info",
null
],
[
"warning",
null
],
[
"error",
null
]
],
"default": "info",
"description": "Select the type of message to display.",
"enum": [
"info",
"warning",
"error"
],
"enumNames": [
null,
null,
null
],
"factory": "Choice",
"title": "Message type",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/message_type"
}
}
},
"required": [
"message",
"message_type"
],
"type": "object"
},
"addview": "plone.actions.Notify",
"description": "Return a portal message to the user",
"title": "Notify user"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"target_folder"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"target_folder": {
"description": "As a path relative to the portal root.",
"factory": "Choice",
"title": "Target folder",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/target_folder"
}
}
},
"required": [
"target_folder"
],
"type": "object"
},
"addview": "plone.actions.Copy",
"description": "Copy the triggering item to a specific folder",
"title": "Copy to folder"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"target_folder"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"target_folder": {
"description": "As a path relative to the portal root.",
"factory": "Choice",
"title": "Target folder",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/target_folder"
}
}
},
"required": [
"target_folder"
],
"type": "object"
},
"addview": "plone.actions.Move",
"description": "Move the triggering item to a specific folder",
"title": "Move to folder"
},
{
"@schema": {
"fieldsets": [],
"properties": {},
"required": [],
"type": "object"
},
"addview": "plone.actions.Delete",
"description": "Delete the triggering item",
"title": "Delete object"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"transition"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"transition": {
"description": "Select the workflow transition to attempt",
"factory": "Choice",
"title": "Transition",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.WorkflowTransitions"
}
}
},
"required": [
"transition"
],
"type": "object"
},
"addview": "plone.actions.Workflow",
"description": "Perform a workflow transition on the triggering object",
"title": "Transition workflow state"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"subject",
"source",
"recipients",
"exclude_actor",
"message"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"exclude_actor": {
"description": "Do not send the email to the user that did the action.",
"factory": "Yes/No",
"title": "Exclude actor from recipients",
"type": "boolean"
},
"message": {
"description": "The message that you want to mail.",
"factory": "Text",
"title": "Message",
"type": "string",
"widget": "textarea"
},
"recipients": {
"description": "The email where you want to send this message. To send it to different email addresses, just separate them with ,",
"factory": "Text line (String)",
"title": "Email recipients",
"type": "string"
},
"source": {
"description": "The email address that sends the email. If no email is provided here, it will use the portal from address.",
"factory": "Text line (String)",
"title": "Email source",
"type": "string"
},
"subject": {
"description": "Subject of the message",
"factory": "Text line (String)",
"title": "Subject",
"type": "string"
}
},
"required": [
"subject",
"recipients",
"message"
],
"type": "object"
},
"addview": "plone.actions.Mail",
"description": "Send an email on the triggering object",
"title": "Send email"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"comment"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"comment": {
"description": "The comment added to the history while versioning the content.",
"factory": "Text line (String)",
"title": "Comment",
"type": "string"
}
},
"required": [],
"type": "object"
},
"addview": "plone.actions.Versioning",
"description": "Store a new version of the object",
"title": "Version object"
}
],
"addable_conditions": [
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"check_types"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"check_types": {
"additionalItems": true,
"description": "The content type to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.ReallyUserFriendlyTypes"
}
},
"title": "Content type",
"type": "array",
"uniqueItems": true
}
},
"required": [
"check_types"
],
"type": "object"
},
"addview": "plone.conditions.PortalType",
"description": "Apply only when the current content object is of a particular type",
"title": "Content type"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"file_extension"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"file_extension": {
"description": "The file extension to check for",
"factory": "Text line (String)",
"title": "File extension",
"type": "string"
}
},
"required": [
"file_extension"
],
"type": "object"
},
"addview": "plone.conditions.FileExtension",
"description": "Apply only to a particular file extension",
"title": "File Extension"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"wf_states"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"wf_states": {
"additionalItems": true,
"description": "The workflow states to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.WorkflowStates"
}
},
"title": "Workflow state",
"type": "array",
"uniqueItems": true
}
},
"required": [
"wf_states"
],
"type": "object"
},
"addview": "plone.conditions.WorkflowState",
"description": "Apply only to a objects in a particular workflow state",
"title": "Workflow state"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"group_names"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"group_names": {
"additionalItems": true,
"description": "The name of the group.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Groups"
}
},
"title": "Group name",
"type": "array",
"uniqueItems": true
}
},
"required": [
"group_names"
],
"type": "object"
},
"addview": "plone.conditions.Group",
"description": "Apply only when the current user is in the given group",
"title": "User's group"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"role_names"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"role_names": {
"additionalItems": true,
"description": "The roles to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Roles"
}
},
"title": "Roles",
"type": "array",
"uniqueItems": true
}
},
"required": [
"role_names"
],
"type": "object"
},
"addview": "plone.conditions.Role",
"description": "Apply only when the current user has the given role",
"title": "User's role"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"tales_expression"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"tales_expression": {
"description": "The TALES expression to check.",
"factory": "Text line (String)",
"title": "TALES expression",
"type": "string"
}
},
"required": [
"tales_expression"
],
"type": "object"
},
"addview": "plone.conditions.TalesExpression",
"description": "Apply only when the result of a TALES expression is True",
"title": "TALES expression"
}
],
"assignments": [],
"cascading": false,
"conditions": [
{
"description": "Apply only when the current content object is of a particular type",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++0/edit",
"first": true,
"idx": 0,
"last": true,
"summary": "Content types are: ${names}",
"title": "Content type"
}
],
"description": "Third rule added in the testing setup",
"enabled": true,
"event": "Comment added",
"group": "Content",
"id": "rule-3",
"stop": false,
"title": "Third test rule"
}
Creating a new Action on a Content rule with POST
#
To create a new action on a content rule, send a POST
request to the
/@controlpanels/content-rules/{rule-id}/action
endpoint, specifying the
action type in the payload:
POST /plone/@controlpanels/content-rules/rule-3/action HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{
"Level": "20",
"message": "text_contentrules_logger_message",
"targetLogger": "Plone",
"type": "plone.actions.Logger"
}
curl -i -X POST http://nohost/plone/@controlpanels/content-rules/rule-3/action -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"Level": "20", "message": "text_contentrules_logger_message", "targetLogger": "Plone", "type": "plone.actions.Logger"}' --user admin:secret
echo '{
"Level": "20",
"message": "text_contentrules_logger_message",
"targetLogger": "Plone",
"type": "plone.actions.Logger"
}' | http POST http://nohost/plone/@controlpanels/content-rules/rule-3/action Accept:application/json Content-Type:application/json -a admin:secret
requests.post('http://nohost/plone/@controlpanels/content-rules/rule-3/action', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'Level': '20', 'message': 'text_contentrules_logger_message', 'targetLogger': 'Plone', 'type': 'plone.actions.Logger'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 201 Created
Content-Type: application/json
Location: http://localhost:55001/plone/@controlpanels/content-rules/rule-3
{
"@id": "http://localhost:55001/plone/@controlpanels/content-rules/rule-3",
"actions": [
{
"description": "Log a particular event",
"editview": "http://localhost:55001/plone/++rule++rule-3/++action++0/edit",
"first": true,
"idx": 0,
"last": true,
"summary": "Log message ${message}",
"title": "Logger"
}
],
"addable_actions": [
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"targetLogger",
"loggingLevel",
"message"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"loggingLevel": {
"default": 20,
"description": "",
"factory": "Integer",
"title": "Logging level",
"type": "integer"
},
"message": {
"default": "text_contentrules_logger_message",
"description": "&e = the triggering event, &c = the context, &u = the user",
"factory": "Text line (String)",
"title": "Message",
"type": "string"
},
"targetLogger": {
"default": "Plone",
"description": "",
"factory": "Text line (String)",
"title": "Logger name",
"type": "string"
}
},
"required": [
"targetLogger",
"loggingLevel",
"message"
],
"type": "object"
},
"addview": "plone.actions.Logger",
"description": "Log a particular event",
"title": "Logger"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"message",
"message_type"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"message": {
"description": "The message to send to the user.",
"factory": "Text line (String)",
"title": "Message",
"type": "string"
},
"message_type": {
"choices": [
[
"info",
null
],
[
"warning",
null
],
[
"error",
null
]
],
"default": "info",
"description": "Select the type of message to display.",
"enum": [
"info",
"warning",
"error"
],
"enumNames": [
null,
null,
null
],
"factory": "Choice",
"title": "Message type",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/message_type"
}
}
},
"required": [
"message",
"message_type"
],
"type": "object"
},
"addview": "plone.actions.Notify",
"description": "Return a portal message to the user",
"title": "Notify user"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"target_folder"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"target_folder": {
"description": "As a path relative to the portal root.",
"factory": "Choice",
"title": "Target folder",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/target_folder"
}
}
},
"required": [
"target_folder"
],
"type": "object"
},
"addview": "plone.actions.Copy",
"description": "Copy the triggering item to a specific folder",
"title": "Copy to folder"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"target_folder"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"target_folder": {
"description": "As a path relative to the portal root.",
"factory": "Choice",
"title": "Target folder",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/target_folder"
}
}
},
"required": [
"target_folder"
],
"type": "object"
},
"addview": "plone.actions.Move",
"description": "Move the triggering item to a specific folder",
"title": "Move to folder"
},
{
"@schema": {
"fieldsets": [],
"properties": {},
"required": [],
"type": "object"
},
"addview": "plone.actions.Delete",
"description": "Delete the triggering item",
"title": "Delete object"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"transition"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"transition": {
"description": "Select the workflow transition to attempt",
"factory": "Choice",
"title": "Transition",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.WorkflowTransitions"
}
}
},
"required": [
"transition"
],
"type": "object"
},
"addview": "plone.actions.Workflow",
"description": "Perform a workflow transition on the triggering object",
"title": "Transition workflow state"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"subject",
"source",
"recipients",
"exclude_actor",
"message"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"exclude_actor": {
"description": "Do not send the email to the user that did the action.",
"factory": "Yes/No",
"title": "Exclude actor from recipients",
"type": "boolean"
},
"message": {
"description": "The message that you want to mail.",
"factory": "Text",
"title": "Message",
"type": "string",
"widget": "textarea"
},
"recipients": {
"description": "The email where you want to send this message. To send it to different email addresses, just separate them with ,",
"factory": "Text line (String)",
"title": "Email recipients",
"type": "string"
},
"source": {
"description": "The email address that sends the email. If no email is provided here, it will use the portal from address.",
"factory": "Text line (String)",
"title": "Email source",
"type": "string"
},
"subject": {
"description": "Subject of the message",
"factory": "Text line (String)",
"title": "Subject",
"type": "string"
}
},
"required": [
"subject",
"recipients",
"message"
],
"type": "object"
},
"addview": "plone.actions.Mail",
"description": "Send an email on the triggering object",
"title": "Send email"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"comment"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"comment": {
"description": "The comment added to the history while versioning the content.",
"factory": "Text line (String)",
"title": "Comment",
"type": "string"
}
},
"required": [],
"type": "object"
},
"addview": "plone.actions.Versioning",
"description": "Store a new version of the object",
"title": "Version object"
}
],
"addable_conditions": [
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"check_types"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"check_types": {
"additionalItems": true,
"description": "The content type to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.ReallyUserFriendlyTypes"
}
},
"title": "Content type",
"type": "array",
"uniqueItems": true
}
},
"required": [
"check_types"
],
"type": "object"
},
"addview": "plone.conditions.PortalType",
"description": "Apply only when the current content object is of a particular type",
"title": "Content type"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"file_extension"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"file_extension": {
"description": "The file extension to check for",
"factory": "Text line (String)",
"title": "File extension",
"type": "string"
}
},
"required": [
"file_extension"
],
"type": "object"
},
"addview": "plone.conditions.FileExtension",
"description": "Apply only to a particular file extension",
"title": "File Extension"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"wf_states"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"wf_states": {
"additionalItems": true,
"description": "The workflow states to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.WorkflowStates"
}
},
"title": "Workflow state",
"type": "array",
"uniqueItems": true
}
},
"required": [
"wf_states"
],
"type": "object"
},
"addview": "plone.conditions.WorkflowState",
"description": "Apply only to a objects in a particular workflow state",
"title": "Workflow state"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"group_names"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"group_names": {
"additionalItems": true,
"description": "The name of the group.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Groups"
}
},
"title": "Group name",
"type": "array",
"uniqueItems": true
}
},
"required": [
"group_names"
],
"type": "object"
},
"addview": "plone.conditions.Group",
"description": "Apply only when the current user is in the given group",
"title": "User's group"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"role_names"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"role_names": {
"additionalItems": true,
"description": "The roles to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Roles"
}
},
"title": "Roles",
"type": "array",
"uniqueItems": true
}
},
"required": [
"role_names"
],
"type": "object"
},
"addview": "plone.conditions.Role",
"description": "Apply only when the current user has the given role",
"title": "User's role"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"tales_expression"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"tales_expression": {
"description": "The TALES expression to check.",
"factory": "Text line (String)",
"title": "TALES expression",
"type": "string"
}
},
"required": [
"tales_expression"
],
"type": "object"
},
"addview": "plone.conditions.TalesExpression",
"description": "Apply only when the result of a TALES expression is True",
"title": "TALES expression"
}
],
"assignments": [],
"cascading": false,
"conditions": [
{
"description": "Apply only when the current content object is of a particular type",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++0/edit",
"first": true,
"idx": 0,
"last": false,
"summary": "Content types are: ${names}",
"title": "Content type"
},
{
"description": "Apply only to a particular file extension",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++1/edit",
"first": false,
"idx": 1,
"last": false,
"summary": "File extension is ${ext}",
"title": "File Extension"
},
{
"description": "Apply only to a objects in a particular workflow state",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++2/edit",
"first": false,
"idx": 2,
"last": false,
"summary": "Workflow states are: ${states}",
"title": "Workflow state"
},
{
"description": "Apply only when the current user is in the given group",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++3/edit",
"first": false,
"idx": 3,
"last": false,
"summary": "Groups are: ${names}",
"title": "User's group"
},
{
"description": "Apply only when the current user has the given role",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++4/edit",
"first": false,
"idx": 4,
"last": false,
"summary": "Roles are: ${names}",
"title": "User's role"
},
{
"description": "Apply only when the result of a TALES expression is True",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++5/edit",
"first": false,
"idx": 5,
"last": true,
"summary": "TALES expression is: ${tales_expression}",
"title": "TALES expression"
}
],
"description": "Third rule added in the testing setup",
"enabled": true,
"event": "Comment added",
"group": "Content",
"id": "rule-3",
"stop": false,
"title": "Third test rule"
}
Reading a Content rule with GET
#
After a successful POST
, access the content rule by sending a GET
request to the endpoint /@controlpanels/content-rules/{rule-id}
:
GET /plone/@controlpanels/content-rules/rule-3 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl -i -X GET http://nohost/plone/@controlpanels/content-rules/rule-3 -H "Accept: application/json" --user admin:secret
http http://nohost/plone/@controlpanels/content-rules/rule-3 Accept:application/json -a admin:secret
requests.get('http://nohost/plone/@controlpanels/content-rules/rule-3', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"@id": "http://localhost:55001/plone/@controlpanels/content-rules/rule-3",
"actions": [
{
"description": "Log a particular event",
"editview": "http://localhost:55001/plone/++rule++rule-3/++action++0/edit",
"first": true,
"idx": 0,
"last": false,
"summary": "Log message text_contentrules_logger_message",
"title": "Logger"
},
{
"description": "Return a portal message to the user",
"editview": "http://localhost:55001/plone/++rule++rule-3/++action++1/edit",
"first": false,
"idx": 1,
"last": false,
"summary": "Notify with message Information",
"title": "Notify user"
},
{
"description": "Copy the triggering item to a specific folder",
"editview": "http://localhost:55001/plone/++rule++rule-3/++action++2/edit",
"first": false,
"idx": 2,
"last": false,
"summary": "Copy to folder /folder.",
"title": "Copy to folder"
},
{
"description": "Move the triggering item to a specific folder",
"editview": "http://localhost:55001/plone/++rule++rule-3/++action++3/edit",
"first": false,
"idx": 3,
"last": false,
"summary": "Move to folder /folder",
"title": "Move to folder"
},
{
"description": "Delete the triggering item",
"editview": null,
"first": false,
"idx": 4,
"last": false,
"summary": "Delete object",
"title": "Delete object"
},
{
"description": "Perform a workflow transition on the triggering object",
"editview": "http://localhost:55001/plone/++rule++rule-3/++action++5/edit",
"first": false,
"idx": 5,
"last": false,
"summary": "Execute transition hide",
"title": "Transition workflow state"
},
{
"description": "Send an email on the triggering object",
"editview": "http://localhost:55001/plone/++rule++rule-3/++action++6/edit",
"first": false,
"idx": 6,
"last": false,
"summary": "Email report to test@somethingelse.com",
"title": "Send email"
},
{
"description": "Store a new version of the object",
"editview": "http://localhost:55001/plone/++rule++rule-3/++action++7/edit",
"first": false,
"idx": 7,
"last": true,
"summary": "Versioning with comment Some comment",
"title": "Version object"
}
],
"addable_actions": [
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"targetLogger",
"loggingLevel",
"message"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"loggingLevel": {
"default": 20,
"description": "",
"factory": "Integer",
"title": "Logging level",
"type": "integer"
},
"message": {
"default": "Caught &e at &c by &u",
"description": "&e = the triggering event, &c = the context, &u = the user",
"factory": "Text line (String)",
"title": "Message",
"type": "string"
},
"targetLogger": {
"default": "Plone",
"description": "",
"factory": "Text line (String)",
"title": "Logger name",
"type": "string"
}
},
"required": [
"targetLogger",
"loggingLevel",
"message"
],
"type": "object"
},
"addview": "plone.actions.Logger",
"description": "Log a particular event",
"title": "Logger"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"message",
"message_type"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"message": {
"description": "The message to send to the user.",
"factory": "Text line (String)",
"title": "Message",
"type": "string"
},
"message_type": {
"choices": [
[
"info",
null
],
[
"warning",
null
],
[
"error",
null
]
],
"default": "info",
"description": "Select the type of message to display.",
"enum": [
"info",
"warning",
"error"
],
"enumNames": [
null,
null,
null
],
"factory": "Choice",
"title": "Message type",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/message_type"
}
}
},
"required": [
"message",
"message_type"
],
"type": "object"
},
"addview": "plone.actions.Notify",
"description": "Return a portal message to the user",
"title": "Notify user"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"target_folder"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"target_folder": {
"description": "As a path relative to the portal root.",
"factory": "Choice",
"title": "Target folder",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/target_folder"
}
}
},
"required": [
"target_folder"
],
"type": "object"
},
"addview": "plone.actions.Copy",
"description": "Copy the triggering item to a specific folder",
"title": "Copy to folder"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"target_folder"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"target_folder": {
"description": "As a path relative to the portal root.",
"factory": "Choice",
"title": "Target folder",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@sources/target_folder"
}
}
},
"required": [
"target_folder"
],
"type": "object"
},
"addview": "plone.actions.Move",
"description": "Move the triggering item to a specific folder",
"title": "Move to folder"
},
{
"@schema": {
"fieldsets": [],
"properties": {},
"required": [],
"type": "object"
},
"addview": "plone.actions.Delete",
"description": "Delete the triggering item",
"title": "Delete object"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"transition"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"transition": {
"description": "Select the workflow transition to attempt",
"factory": "Choice",
"title": "Transition",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.WorkflowTransitions"
}
}
},
"required": [
"transition"
],
"type": "object"
},
"addview": "plone.actions.Workflow",
"description": "Perform a workflow transition on the triggering object",
"title": "Transition workflow state"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"subject",
"source",
"recipients",
"exclude_actor",
"message"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"exclude_actor": {
"description": "Do not send the email to the user that did the action.",
"factory": "Yes/No",
"title": "Exclude actor from recipients",
"type": "boolean"
},
"message": {
"description": "The message that you want to mail.",
"factory": "Text",
"title": "Message",
"type": "string",
"widget": "textarea"
},
"recipients": {
"description": "The email where you want to send this message. To send it to different email addresses, just separate them with ,",
"factory": "Text line (String)",
"title": "Email recipients",
"type": "string"
},
"source": {
"description": "The email address that sends the email. If no email is provided here, it will use the portal from address.",
"factory": "Text line (String)",
"title": "Email source",
"type": "string"
},
"subject": {
"description": "Subject of the message",
"factory": "Text line (String)",
"title": "Subject",
"type": "string"
}
},
"required": [
"subject",
"recipients",
"message"
],
"type": "object"
},
"addview": "plone.actions.Mail",
"description": "Send an email on the triggering object",
"title": "Send email"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"comment"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"comment": {
"description": "The comment added to the history while versioning the content.",
"factory": "Text line (String)",
"title": "Comment",
"type": "string"
}
},
"required": [],
"type": "object"
},
"addview": "plone.actions.Versioning",
"description": "Store a new version of the object",
"title": "Version object"
}
],
"addable_conditions": [
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"check_types"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"check_types": {
"additionalItems": true,
"description": "The content type to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.ReallyUserFriendlyTypes"
}
},
"title": "Content type",
"type": "array",
"uniqueItems": true
}
},
"required": [
"check_types"
],
"type": "object"
},
"addview": "plone.conditions.PortalType",
"description": "Apply only when the current content object is of a particular type",
"title": "Content type"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"file_extension"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"file_extension": {
"description": "The file extension to check for",
"factory": "Text line (String)",
"title": "File extension",
"type": "string"
}
},
"required": [
"file_extension"
],
"type": "object"
},
"addview": "plone.conditions.FileExtension",
"description": "Apply only to a particular file extension",
"title": "File Extension"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"wf_states"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"wf_states": {
"additionalItems": true,
"description": "The workflow states to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.WorkflowStates"
}
},
"title": "Workflow state",
"type": "array",
"uniqueItems": true
}
},
"required": [
"wf_states"
],
"type": "object"
},
"addview": "plone.conditions.WorkflowState",
"description": "Apply only to a objects in a particular workflow state",
"title": "Workflow state"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"group_names"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"group_names": {
"additionalItems": true,
"description": "The name of the group.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Groups"
}
},
"title": "Group name",
"type": "array",
"uniqueItems": true
}
},
"required": [
"group_names"
],
"type": "object"
},
"addview": "plone.conditions.Group",
"description": "Apply only when the current user is in the given group",
"title": "User's group"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"role_names"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"role_names": {
"additionalItems": true,
"description": "The roles to check for.",
"factory": "Multiple Choice",
"items": {
"description": "",
"factory": "Choice",
"title": "",
"type": "string",
"vocabulary": {
"@id": "http://localhost:55001/plone/@vocabularies/plone.app.vocabularies.Roles"
}
},
"title": "Roles",
"type": "array",
"uniqueItems": true
}
},
"required": [
"role_names"
],
"type": "object"
},
"addview": "plone.conditions.Role",
"description": "Apply only when the current user has the given role",
"title": "User's role"
},
{
"@schema": {
"fieldsets": [
{
"behavior": "plone",
"fields": [
"tales_expression"
],
"id": "default",
"title": "Default"
}
],
"properties": {
"tales_expression": {
"description": "The TALES expression to check.",
"factory": "Text line (String)",
"title": "TALES expression",
"type": "string"
}
},
"required": [
"tales_expression"
],
"type": "object"
},
"addview": "plone.conditions.TalesExpression",
"description": "Apply only when the result of a TALES expression is True",
"title": "TALES expression"
}
],
"assignments": [],
"cascading": false,
"conditions": [
{
"description": "Apply only when the current content object is of a particular type",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++0/edit",
"first": true,
"idx": 0,
"last": false,
"summary": "Content types are: Collection",
"title": "Content type"
},
{
"description": "Apply only to a particular file extension",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++1/edit",
"first": false,
"idx": 1,
"last": false,
"summary": "File extension is JPG",
"title": "File Extension"
},
{
"description": "Apply only to a objects in a particular workflow state",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++2/edit",
"first": false,
"idx": 2,
"last": false,
"summary": "Workflow states are: pending, private",
"title": "Workflow state"
},
{
"description": "Apply only when the current user is in the given group",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++3/edit",
"first": false,
"idx": 3,
"last": false,
"summary": "Groups are: Administrators, Site Administrators",
"title": "User's group"
},
{
"description": "Apply only when the current user has the given role",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++4/edit",
"first": false,
"idx": 4,
"last": false,
"summary": "Roles are: Anonymous, Authenticated",
"title": "User's role"
},
{
"description": "Apply only when the result of a TALES expression is True",
"editview": "http://localhost:55001/plone/++rule++rule-3/++condition++5/edit",
"first": false,
"idx": 5,
"last": true,
"summary": "TALES expression is: <tal:block content='string:' />",
"title": "TALES expression"
}
],
"description": "Third rule added in the testing setup",
"enabled": true,
"event": "Comment added",
"group": "Content",
"id": "rule-3",
"stop": false,
"title": "Third test rule"
}
Updating a Content rule with PATCH
#
To update an existing content rule, send a PATCH
request to the server.
PATCH
allows to provide just a subset of the resource, that is, the values you actually want to change:
PATCH /plone/@controlpanels/content-rules/rule-3 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{
"cascading": true,
"description": "Third rule added in the testing setup (modified)",
"enabled": false,
"event": "Comment removed",
"stop": true,
"title": "Third test rule (modified)"
}
curl -i -X PATCH http://nohost/plone/@controlpanels/content-rules/rule-3 -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"cascading": true, "description": "Third rule added in the testing setup (modified)", "enabled": false, "event": "Comment removed", "stop": true, "title": "Third test rule (modified)"}' --user admin:secret
echo '{
"cascading": true,
"description": "Third rule added in the testing setup (modified)",
"enabled": false,
"event": "Comment removed",
"stop": true,
"title": "Third test rule (modified)"
}' | http PATCH http://nohost/plone/@controlpanels/content-rules/rule-3 Accept:application/json Content-Type:application/json -a admin:secret
requests.patch('http://nohost/plone/@controlpanels/content-rules/rule-3', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'cascading': True, 'description': 'Third rule added in the testing setup (modified)', 'enabled': False, 'event': 'Comment removed', 'stop': True, 'title': 'Third test rule (modified)'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 204 No Content
Updating a Condition on a Content rule with PATCH
#
To update an existing condition on a content rule, send a PATCH
request to the server.
PATCH
allows to provide just a subset of the resource, that is, the values you actually want to change:
PATCH /plone/@controlpanels/content-rules/rule-3/condition/0 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{
"check_types": [
"Collection"
]
}
curl -i -X PATCH http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0 -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"check_types": ["Collection"]}' --user admin:secret
echo '{
"check_types": [
"Collection"
]
}' | http PATCH http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0 Accept:application/json Content-Type:application/json -a admin:secret
requests.patch('http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'check_types': ['Collection']}, auth=('admin', 'secret'))
Response:
HTTP/1.1 204 No Content
Updating an Action on a Content rule with PATCH
#
To update an existing action on a content rule, send a PATCH
request to the server.
PATCH
allows to provide just a subset of the resource, that is, the values you actually want to change:
PATCH /plone/@controlpanels/content-rules/rule-3/action/0 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{
"Level": "20",
"message": "text_contentrules_logger_message",
"targetLogger": "Plone6"
}
curl -i -X PATCH http://nohost/plone/@controlpanels/content-rules/rule-3/action/0 -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"Level": "20", "message": "text_contentrules_logger_message", "targetLogger": "Plone6"}' --user admin:secret
echo '{
"Level": "20",
"message": "text_contentrules_logger_message",
"targetLogger": "Plone6"
}' | http PATCH http://nohost/plone/@controlpanels/content-rules/rule-3/action/0 Accept:application/json Content-Type:application/json -a admin:secret
requests.patch('http://nohost/plone/@controlpanels/content-rules/rule-3/action/0', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'Level': '20', 'message': 'text_contentrules_logger_message', 'targetLogger': 'Plone6'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 204 No Content
Removing a Content rule with DELETE
#
Delete an existing content rule by sending a DELETE
request to the URL of an existing content rule:
DELETE /plone/@controlpanels/content-rules/rule-3 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl -i -X DELETE http://nohost/plone/@controlpanels/content-rules/rule-3 -H "Accept: application/json" --user admin:secret
http DELETE http://nohost/plone/@controlpanels/content-rules/rule-3 Accept:application/json -a admin:secret
requests.delete('http://nohost/plone/@controlpanels/content-rules/rule-3', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 204 No Content
Removing a Condition on a Content rule with DELETE
#
Delete an existing condition from a content rule by sending a DELETE
request to the URL of an existing content rule:
DELETE /plone/@controlpanels/content-rules/rule-3/condition/0 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl -i -X DELETE http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0 -H "Accept: application/json" --user admin:secret
http DELETE http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0 Accept:application/json -a admin:secret
requests.delete('http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 204 No Content
Removing an Action on a Content rule with DELETE
#
Delete an existing action from a content rule by sending a DELETE
request to the URL of an existing content rule:
DELETE /plone/@controlpanels/content-rules/rule-3/condition/0 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl -i -X DELETE http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0 -H "Accept: application/json" --user admin:secret
http DELETE http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0 Accept:application/json -a admin:secret
requests.delete('http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 204 No Content