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:

http

GET /plone/@controlpanels HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET http://nohost/plone/@controlpanels -H "Accept: application/json" --user admin:secret

httpie

http http://nohost/plone/@controlpanels Accept:application/json -a admin:secret

python-requests

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 panel

  • title: the title of the control panel

  • group: the group in which the control panel should appear, for example, General, Content, Users, Security, Advanced, or Add-on Configuration.

Retrieve a single Control Panel#

To retrieve a single control panel, send a GET request to the URL of the control panel:

http

GET /plone/@controlpanels/editing HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET http://nohost/plone/@controlpanels/editing -H "Accept: application/json" --user admin:secret

httpie

http http://nohost/plone/@controlpanels/editing Accept:application/json -a admin:secret

python-requests

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 panel

  • title: title of the control panel

  • group: group name of the control panel

  • schema: JSON Schema of the control panel

  • data: 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:

http

PATCH /plone/@controlpanels/editing HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json

{
  "default_editor": "CKeditor",
  "ext_editor": true
}

curl

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

httpie

echo '{
  "default_editor": "CKeditor",
  "ext_editor": true
}' | http PATCH http://nohost/plone/@controlpanels/editing Accept:application/json Content-Type:application/json -a admin:secret

python-requests

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

GET

/@controlpanels/dexterity-types

List configurable content types

POST

/@controlpanels/dexterity-types

Creates a new content type

GET

/@controlpanels/dexterity-types/{type-id}

Get the current state of the content type

PATCH

/@controlpanels/dexterity-types/{type-id}

Update the content type details

DELETE

/@controlpanels/dexterity-types/{type-id}

Remove the content type

Listing Dexterity Content Types#

To list the available content types, send a GET request to @controlpanels/dexterity-types

http

GET /plone/@controlpanels/dexterity-types HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET http://nohost/plone/@controlpanels/dexterity-types -H "Accept: application/json" --user admin:secret

httpie

http http://nohost/plone/@controlpanels/dexterity-types Accept:application/json -a admin:secret

python-requests

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 panel

  • title: title of the control panel

  • group: group name of the control panel

  • schema: JSON Schema of the control panel

  • data: current values of the control panel

  • items: 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:

http

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

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

httpie

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

python-requests

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}:

http

GET /plone/@controlpanels/dexterity-types/my_custom_content_type HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type -H "Accept: application/json" --user admin:secret

httpie

http http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type Accept:application/json -a admin:secret

python-requests

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:

http

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

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

httpie

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

python-requests

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:

http

DELETE /plone/@controlpanels/dexterity-types/my_custom_content_type HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X DELETE http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type -H "Accept: application/json" --user admin:secret

httpie

http DELETE http://nohost/plone/@controlpanels/dexterity-types/my_custom_content_type Accept:application/json -a admin:secret

python-requests

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

GET

/@controlpanels/content-rules

List configurable content rules

POST

/@controlpanels/content-rules

Creates a new content rule

GET

/@controlpanels/content-rules/{rule-id}

Get the current state of the content rule

PATCH

/@controlpanels/content-rules/{rule-id}

Update the content rule details

DELETE

/@controlpanels/content-rules/{rule-id}

Remove the content rule

Listing Content Rules#

To list the available content rules, send a GET request to @controlpanels/content-rules

http

GET /plone/@controlpanels/content-rules HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET http://nohost/plone/@controlpanels/content-rules -H "Accept: application/json" --user admin:secret

httpie

http http://nohost/plone/@controlpanels/content-rules Accept:application/json -a admin:secret

python-requests

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 rule

  • id: actual id of the content rule

  • assigned: rule assigned or not

  • title: title of the rule

  • description: rule description

  • enabled: rule is enabled or not

  • trigger: triggering event

  • conditions: conditions before triggering the rule

  • actions: 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:

http

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

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

httpie

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

python-requests

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": [
        {
            "addview": "plone.actions.Logger",
            "description": "Log a particular event",
            "title": "Logger"
        },
        {
            "addview": "plone.actions.Notify",
            "description": "Return a portal message to the user",
            "title": "Notify user"
        },
        {
            "addview": "plone.actions.Copy",
            "description": "Copy the triggering item to a specific folder",
            "title": "Copy to folder"
        },
        {
            "addview": "plone.actions.Move",
            "description": "Move the triggering item to a specific folder",
            "title": "Move to folder"
        },
        {
            "addview": "plone.actions.Delete",
            "description": "Delete the triggering item",
            "title": "Delete object"
        },
        {
            "addview": "plone.actions.Workflow",
            "description": "Perform a workflow transition on the triggering object",
            "title": "Transition workflow state"
        },
        {
            "addview": "plone.actions.Mail",
            "description": "Send an email on the triggering object",
            "title": "Send email"
        },
        {
            "addview": "plone.actions.Versioning",
            "description": "Store a new version of the object",
            "title": "Version object"
        }
    ],
    "addable_conditions": [
        {
            "addview": "plone.conditions.PortalType",
            "description": "Apply only when the current content object is of a particular type",
            "title": "Content type"
        },
        {
            "addview": "plone.conditions.FileExtension",
            "description": "Apply only to a particular file extension",
            "title": "File Extension"
        },
        {
            "addview": "plone.conditions.WorkflowState",
            "description": "Apply only to a objects in a particular workflow state",
            "title": "Workflow state"
        },
        {
            "addview": "plone.conditions.Group",
            "description": "Apply only when the current user is in the given group",
            "title": "User's group"
        },
        {
            "addview": "plone.conditions.Role",
            "description": "Apply only when the current user has the given role",
            "title": "User's role"
        },
        {
            "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:

http

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

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

httpie

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

python-requests

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": [
        {
            "addview": "plone.actions.Logger",
            "description": "Log a particular event",
            "title": "Logger"
        },
        {
            "addview": "plone.actions.Notify",
            "description": "Return a portal message to the user",
            "title": "Notify user"
        },
        {
            "addview": "plone.actions.Copy",
            "description": "Copy the triggering item to a specific folder",
            "title": "Copy to folder"
        },
        {
            "addview": "plone.actions.Move",
            "description": "Move the triggering item to a specific folder",
            "title": "Move to folder"
        },
        {
            "addview": "plone.actions.Delete",
            "description": "Delete the triggering item",
            "title": "Delete object"
        },
        {
            "addview": "plone.actions.Workflow",
            "description": "Perform a workflow transition on the triggering object",
            "title": "Transition workflow state"
        },
        {
            "addview": "plone.actions.Mail",
            "description": "Send an email on the triggering object",
            "title": "Send email"
        },
        {
            "addview": "plone.actions.Versioning",
            "description": "Store a new version of the object",
            "title": "Version object"
        }
    ],
    "addable_conditions": [
        {
            "addview": "plone.conditions.PortalType",
            "description": "Apply only when the current content object is of a particular type",
            "title": "Content type"
        },
        {
            "addview": "plone.conditions.FileExtension",
            "description": "Apply only to a particular file extension",
            "title": "File Extension"
        },
        {
            "addview": "plone.conditions.WorkflowState",
            "description": "Apply only to a objects in a particular workflow state",
            "title": "Workflow state"
        },
        {
            "addview": "plone.conditions.Group",
            "description": "Apply only when the current user is in the given group",
            "title": "User's group"
        },
        {
            "addview": "plone.conditions.Role",
            "description": "Apply only when the current user has the given role",
            "title": "User's role"
        },
        {
            "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:

http

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

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

httpie

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

python-requests

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": [
        {
            "addview": "plone.actions.Logger",
            "description": "Log a particular event",
            "title": "Logger"
        },
        {
            "addview": "plone.actions.Notify",
            "description": "Return a portal message to the user",
            "title": "Notify user"
        },
        {
            "addview": "plone.actions.Copy",
            "description": "Copy the triggering item to a specific folder",
            "title": "Copy to folder"
        },
        {
            "addview": "plone.actions.Move",
            "description": "Move the triggering item to a specific folder",
            "title": "Move to folder"
        },
        {
            "addview": "plone.actions.Delete",
            "description": "Delete the triggering item",
            "title": "Delete object"
        },
        {
            "addview": "plone.actions.Workflow",
            "description": "Perform a workflow transition on the triggering object",
            "title": "Transition workflow state"
        },
        {
            "addview": "plone.actions.Mail",
            "description": "Send an email on the triggering object",
            "title": "Send email"
        },
        {
            "addview": "plone.actions.Versioning",
            "description": "Store a new version of the object",
            "title": "Version object"
        }
    ],
    "addable_conditions": [
        {
            "addview": "plone.conditions.PortalType",
            "description": "Apply only when the current content object is of a particular type",
            "title": "Content type"
        },
        {
            "addview": "plone.conditions.FileExtension",
            "description": "Apply only to a particular file extension",
            "title": "File Extension"
        },
        {
            "addview": "plone.conditions.WorkflowState",
            "description": "Apply only to a objects in a particular workflow state",
            "title": "Workflow state"
        },
        {
            "addview": "plone.conditions.Group",
            "description": "Apply only when the current user is in the given group",
            "title": "User's group"
        },
        {
            "addview": "plone.conditions.Role",
            "description": "Apply only when the current user has the given role",
            "title": "User's role"
        },
        {
            "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}:

http

GET /plone/@controlpanels/content-rules/rule-3 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X GET http://nohost/plone/@controlpanels/content-rules/rule-3 -H "Accept: application/json" --user admin:secret

httpie

http http://nohost/plone/@controlpanels/content-rules/rule-3 Accept:application/json -a admin:secret

python-requests

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": [
        {
            "addview": "plone.actions.Logger",
            "description": "Log a particular event",
            "title": "Logger"
        },
        {
            "addview": "plone.actions.Notify",
            "description": "Return a portal message to the user",
            "title": "Notify user"
        },
        {
            "addview": "plone.actions.Copy",
            "description": "Copy the triggering item to a specific folder",
            "title": "Copy to folder"
        },
        {
            "addview": "plone.actions.Move",
            "description": "Move the triggering item to a specific folder",
            "title": "Move to folder"
        },
        {
            "addview": "plone.actions.Delete",
            "description": "Delete the triggering item",
            "title": "Delete object"
        },
        {
            "addview": "plone.actions.Workflow",
            "description": "Perform a workflow transition on the triggering object",
            "title": "Transition workflow state"
        },
        {
            "addview": "plone.actions.Mail",
            "description": "Send an email on the triggering object",
            "title": "Send email"
        },
        {
            "addview": "plone.actions.Versioning",
            "description": "Store a new version of the object",
            "title": "Version object"
        }
    ],
    "addable_conditions": [
        {
            "addview": "plone.conditions.PortalType",
            "description": "Apply only when the current content object is of a particular type",
            "title": "Content type"
        },
        {
            "addview": "plone.conditions.FileExtension",
            "description": "Apply only to a particular file extension",
            "title": "File Extension"
        },
        {
            "addview": "plone.conditions.WorkflowState",
            "description": "Apply only to a objects in a particular workflow state",
            "title": "Workflow state"
        },
        {
            "addview": "plone.conditions.Group",
            "description": "Apply only when the current user is in the given group",
            "title": "User's group"
        },
        {
            "addview": "plone.conditions.Role",
            "description": "Apply only when the current user has the given role",
            "title": "User's role"
        },
        {
            "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:

http

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

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

httpie

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

python-requests

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:

http

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

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

httpie

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

python-requests

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:

http

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

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

httpie

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

python-requests

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:

http

DELETE /plone/@controlpanels/content-rules/rule-3 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X DELETE http://nohost/plone/@controlpanels/content-rules/rule-3 -H "Accept: application/json" --user admin:secret

httpie

http DELETE http://nohost/plone/@controlpanels/content-rules/rule-3 Accept:application/json -a admin:secret

python-requests

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:

http

DELETE /plone/@controlpanels/content-rules/rule-3/condition/0 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X DELETE http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0 -H "Accept: application/json" --user admin:secret

httpie

http DELETE http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0 Accept:application/json -a admin:secret

python-requests

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:

http

DELETE /plone/@controlpanels/content-rules/rule-3/condition/0 HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0

curl

curl -i -X DELETE http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0 -H "Accept: application/json" --user admin:secret

httpie

http DELETE http://nohost/plone/@controlpanels/content-rules/rule-3/condition/0 Accept:application/json -a admin:secret

python-requests

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