Create a Plone distribution#
This section explains how a developer can create a custom Plone distribution. A Plone distribution is a pre-packaged version of Plone that includes specific features, themes, modules, and configurations.
See also
For a conceptual guide, see Plone distributions.
Create a backend add-on#
These instructions assume that you already have created a Plone backend add-on package, and now you want to add a distribution to it.
A Plone distribution exists inside a Python package that can be installed by pip
.
Update setup.py
#
Your package should follow conventions that make it discoverable by other developers.
In your setup.py
file, always add the correct Python Trove classifiers.
"Framework :: Plone",
"Framework :: Plone :: 6.1",
"Framework :: Plone :: Distribution",
Add plone.distribution
to your install_requires
stanza in your setup.py
file.
install_requires=[
"Products.CMFPlone",
"setuptools",
"plone.distribution",
],
Update configure.zcml
#
In your main configure.zcml
file, add the plone
XML namespace with the following declaration.
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:plone="http://namespaces.plone.org/plone"
>
Register plone.distribution
as a package to include with the following <include>
directive.
<include package="plone.distribution" />
Then declare the distributions you want to include in your package.
<plone:distribution
name="blog"
title="Personal Blog"
description="A Plone site already configured to host a personal blog."
directory="distributions/blog"
/>
The above example registers a distribution that will configure a personal blog with some default content.
Add distribution handlers#
When registering a distribution, you can provide a pre_handler
, a handler
, and a post_handler
, each of which must be a function with their respective signature, as shown in the following example.
def pre_handler(answers: dict) -> dict:
return answers
def handler(distribution: Distribution, site, answers: dict):
return site
def post_handler(distribution: Distribution, site, answers: dict):
return site
Each of those handlers will be called as follows.
pre_handler
Processes the answers to prepare the distribution before creating the site.
handler
Runs after creating the bare Plone site instead of the default handler. It installs the required GenericSetup profiles and creates the content.
post_handler
Runs after the site is set up.
To add extra configuration to your Plone site, and assuming you added extra inputs to the Plone site creation form, then you can add your own handler, registering it as shown in the following example.
<plone:distribution
name="blog"
title="Personal Blog"
description="A Plone site already configured to host a personal Blog."
directory="distributions/blog"
post_handler=".handlers.blog.post_handler"
/>
Add a distribution folder#
To organize your distribution configuration, you can follow the convention to use the distributions/<distribution_name>
folder in the root of your package.
In that folder, you need to provide the items described in the following sections.
image.png
#
A 1080 pixels wide by 768 pixels tall image in PNG format representing your distribution. It could be the default page of a new site, your logo, or any other way of representing your distribution.
profiles.json
#
A file profiles.json
containing the GenericSetup profiles that your distribution uses during installation.
This file needs to contain two keys.
base
List of profiles to install in every new site using this distribution.
content
List of profiles to install when the user decides to create a site with example content.
As an example, the configuration for a new Plone site with Volto as its frontend would be the following.
{
"base": [
"plone.app.contenttypes:default",
"plone.app.caching:default",
"plonetheme.barceloneta:default",
"plone.volto:default"
],
"content": [
"plone.volto:default-homepage"
]
}
schema.json
#
If you require additional input from the user during site creation, you can customize the form using the schema.json
file.
The file should contain two keys.
schema
A JSON Schema definition.
uischema
A
react-jsonschema-form
configuration to modify the display of the form.
The schema
should have at least the following keys.
site_id
title
description
default_language
portal_timezone
setup_content
The following code example is the content of the schema.json
file for creating the site.
{
"schema": {
"title": "Create a Plone site",
"description": "Adds a new Plone content management system site to the underlying application server.",
"type": "object",
"required": [
"site_id",
"title"
],
"properties": {
"site_id": {
"type": "string",
"title": "Path Identifier",
"default": "Plone",
"description": "The ID of the site. No special characters or spaces are allowed. This ends up as part of the URL unless hidden by an upstream web server."
},
"title": {
"type": "string",
"title": "Title",
"default": "Site",
"description": "A short title for the site. This will be shown as part of the title of the browser window on each page."
},
"description": {
"type": "string",
"title": "Site Description",
"default": "A Plone Site"
},
"default_language": {"$ref": "#/definitions/languages"},
"portal_timezone": {"$ref": "#/definitions/timezones"},
"setup_content": {
"type": "boolean",
"title": "Create Content",
"description": "Should example content be added during site creation?",
"default": false
}
}
},
"uischema": {
}
}
Note
You may have noticed the entries for both default_language
and portal_timezone
.
"default_language": {"$ref": "#/definitions/languages"},
"portal_timezone": {"$ref": "#/definitions/timezones"},
plone.distribution
adds both definitions at runtime, providing a list of languages and timezones available on the installation.
Add a dependency on an add-on#
If you want to add a Plone backend add-on to your Plone distribution, then you must perform the following steps.
Add your add-on, such as collective.person
, to your setup.py
file's install_requires
stanza.
install_requires=[
"setuptools",
"Plone",
"plone.distribution>=1.0.0b2",
"plone.api",
"collective.person",
],
Then add it to your dependencies.zcml
file.
<!-- List all packages your distribution depends on here -->
<include package="plone.volto" />
<include package="plone.restapi" />
<include package="collective.person" />
<include package="plone.distribution" />
</configure>
Finally, add it to your profiles.json
file.
"base": [
"plone.app.contenttypes:default",
"plone.app.caching:default",
"plone.restapi:default",
"plone.volto:default",
"collective.person:default",
"plonetheme.barceloneta:default"
],
Add example content#
The distribution loads its content from JSON data in the content
folder.
To export content from a site into this folder, use the bin/export-distribution
script.
bin/export-distribution path/to/zope.conf Plone
In the example above, Plone
is the ID of the Plone site to export.
Limit available distributions#
By default, Plone 6.1 ships with two ready-to-use distributions.
default
Create a Plone site with the Volto frontend.
classic
Create a Plone site with the Classic UI frontend.
If you want to limit the choice of distributions when creating a new site, you can set the environment variable ALLOWED_DISTRIBUTIONS
to a comma-separated sting of only those distributions' names.
ALLOWED_DISTRIBUTIONS=default