Themes#
Diazo themes can be managed programmatically through the @themes endpoint in a Plone site.
This endpoint requires plone.app.theming to be installed and the cmf.ManagePortal permission.
It is particularly useful in containerized deployments (such as Kubernetes) where access to the Plone UI may not be available.
Listing themes#
A list of all available themes can be retrieved by sending a GET request to the @themes endpoint:
http
GET /plone/@themes HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl
curl -i -X GET http://nohost/plone/@themes -H "Accept: application/json" --user admin:secret
httpie
http http://nohost/plone/@themes Accept:application/json -a admin:secret
python-requests
requests.get('http://nohost/plone/@themes', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"@id": "http://localhost:55001/plone/@themes/plonetheme.barceloneta",
"id": "plonetheme.barceloneta",
"title": "Barceloneta Theme",
"description": "The default Plone 5 theme",
"active": true,
"preview": "++theme++plonetheme.barceloneta/preview.png",
"rules": "++theme++plonetheme.barceloneta/rules.xml"
}
]
The following fields are returned for each theme:
@id: hypermedia link to the theme resourceid: the theme identifiertitle: the friendly name of the themedescription: description of the themeactive: whether this theme is currently activepreview: path to the theme preview image (ornull)rules: path to the theme rules file
Reading a theme#
A single theme can be retrieved by sending a GET request with the theme ID as a path parameter:
http
GET /plone/@themes/plonetheme.barceloneta HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
curl
curl -i -X GET http://nohost/plone/@themes/plonetheme.barceloneta -H "Accept: application/json" --user admin:secret
httpie
http http://nohost/plone/@themes/plonetheme.barceloneta Accept:application/json -a admin:secret
python-requests
requests.get('http://nohost/plone/@themes/plonetheme.barceloneta', headers={'Accept': 'application/json'}, auth=('admin', 'secret'))
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"@id": "http://localhost:55001/plone/@themes/plonetheme.barceloneta",
"id": "plonetheme.barceloneta",
"title": "Barceloneta Theme",
"description": "The default Plone 5 theme",
"active": true,
"preview": "++theme++plonetheme.barceloneta/preview.png",
"rules": "++theme++plonetheme.barceloneta/rules.xml"
}
Uploading a theme#
A new theme can be uploaded by sending a POST request with a ZIP archive as multipart/form-data:
http
POST /plone/@themes HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: multipart/form-data; boundary=---------------------------1234567890
-----------------------------1234567890
Content-Disposition: form-data; name="themeArchive"; filename="mytheme.zip"
Content-Type: application/zip
<binary zip data>
-----------------------------1234567890--
curl
curl -i -X POST http://nohost/plone/@themes -H "Accept: application/json" -H "Content-Type: multipart/form-data; boundary=---------------------------1234567890" --data-raw '-----------------------------1234567890
Content-Disposition: form-data; name="themeArchive"; filename="mytheme.zip"
Content-Type: application/zip
<binary zip data>
-----------------------------1234567890--' --user admin:secret
httpie
echo '-----------------------------1234567890
Content-Disposition: form-data; name="themeArchive"; filename="mytheme.zip"
Content-Type: application/zip
<binary zip data>
-----------------------------1234567890--' | http POST http://nohost/plone/@themes Accept:application/json Content-Type:"multipart/form-data; boundary=---------------------------1234567890" -a admin:secret
python-requests
requests.post('http://nohost/plone/@themes', headers={'Accept': 'application/json', 'Content-Type': 'multipart/form-data; boundary=---------------------------1234567890'}, data='-----------------------------1234567890\r\n\nContent-Disposition: form-data; name="themeArchive"; filename="mytheme.zip"\r\n\nContent-Type: application/zip\r\n\n\r\n\n<binary zip data>\r\n\n-----------------------------1234567890--', auth=('admin', 'secret'))
Response:
HTTP/1.1 201 Created
Content-Type: application/json
{
"@id": "http://localhost:55001/plone/@themes/mytheme",
"id": "mytheme",
"title": "My Theme",
"description": "",
"active": false,
"preview": null,
"rules": "/++theme++mytheme/rules.xml"
}
The following form fields are accepted:
themeArchive(required): the ZIP file containing the themeenable(optional): set totrueto activate the theme immediately after uploadreplace(optional): set totrueto overwrite an existing theme with the same ID
Activating a theme#
A theme can be activated by sending a PATCH request with {"active": true}:
http
PATCH /plone/@themes/plonetheme.barceloneta HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{"active": true}
curl
curl -i -X PATCH http://nohost/plone/@themes/plonetheme.barceloneta -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"active": true}' --user admin:secret
httpie
echo '{
"active": true
}' | http PATCH http://nohost/plone/@themes/plonetheme.barceloneta Accept:application/json Content-Type:application/json -a admin:secret
python-requests
requests.patch('http://nohost/plone/@themes/plonetheme.barceloneta', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'active': True}, auth=('admin', 'secret'))
Response:
HTTP/1.1 204 No Content
Deactivating a theme#
A theme can be deactivated by sending a PATCH request with {"active": false}:
http
PATCH /plone/@themes/plonetheme.barceloneta HTTP/1.1
Accept: application/json
Authorization: Basic YWRtaW46c2VjcmV0
Content-Type: application/json
{"active": false}
curl
curl -i -X PATCH http://nohost/plone/@themes/plonetheme.barceloneta -H "Accept: application/json" -H "Content-Type: application/json" --data-raw '{"active": false}' --user admin:secret
httpie
echo '{
"active": false
}' | http PATCH http://nohost/plone/@themes/plonetheme.barceloneta Accept:application/json Content-Type:application/json -a admin:secret
python-requests
requests.patch('http://nohost/plone/@themes/plonetheme.barceloneta', headers={'Accept': 'application/json', 'Content-Type': 'application/json'}, json={'active': False}, auth=('admin', 'secret'))
Response:
HTTP/1.1 204 No Content