Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
7f80616
Update year in trainings title, create venv with uv
davisagli Jul 20, 2026
6c8e5a4
index copy editing
davisagli Jul 20, 2026
bd06444
revise about_mastering
davisagli Jul 20, 2026
f637d32
revise intro
davisagli Jul 20, 2026
cef40f2
revise what_is_plone
davisagli Jul 20, 2026
267a2e4
update installation for new monorepo project
davisagli Jul 21, 2026
2558e28
revise features (and move some sections to installation)
davisagli Jul 21, 2026
1d8f2ac
revise configuring_customizing
davisagli Jul 22, 2026
c6db2a7
Fix CI (set up uv)
davisagli Jul 22, 2026
8700a71
revise extending
davisagli Jul 22, 2026
d871fa8
revise dexterity
davisagli Jul 22, 2026
298002a
revise volto_development
davisagli Jul 22, 2026
b1a96c6
revise dexterity_2_talk
davisagli Jul 22, 2026
1042600
revise dexterity_reference
davisagli Jul 22, 2026
59f0aa9
revise volto_overrides
davisagli Jul 23, 2026
a0a2c9e
revise volto_talkview
davisagli Jul 23, 2026
4f46bd1
fix
davisagli Jul 23, 2026
7aa9b08
revise behaviors_1
davisagli Jul 24, 2026
5bbbe83
revise volto_frontpage
davisagli Jul 24, 2026
6af174d
revise api
davisagli Jul 24, 2026
bc15b53
revise events
davisagli Jul 24, 2026
8b231ba
revise vocabularies
davisagli Jul 29, 2026
8ecfb26
revise search
davisagli Jul 29, 2026
d987371
revise volto_testing
davisagli Jul 30, 2026
507379f
revise dexterity_3
davisagli Jul 30, 2026
acfa4c5
revise upgrade_steps
davisagli Jul 30, 2026
d3079bd
revise volto_listing_variation
davisagli Jul 31, 2026
40adc9b
revise searchable
davisagli Jul 31, 2026
b515888
revise volto_components_sponsors
davisagli Aug 1, 2026
11bf1aa
revise addons
davisagli Aug 3, 2026
afe12c5
revise custom_block
davisagli Aug 4, 2026
ff5ea08
revise user_generated_content
davisagli Aug 5, 2026
211f6f7
update training title
davisagli Aug 5, 2026
12922a0
revise relations
davisagli Aug 6, 2026
e97a091
revise voting-story/index
davisagli Aug 13, 2026
5edc903
revise voting-story/behaviors_2
davisagli Aug 29, 2026
bde7f8a
revise voting-story/endpoints
davisagli Aug 30, 2026
836eb38
revise voting-story/volto_actions
davisagli Aug 31, 2026
42ba7b2
change relations widget
pbauer Sep 1, 2026
4050327
revise voting-story/permissions
davisagli Sep 5, 2026
2662b0b
copy editing
davisagli Sep 5, 2026
5a8fcb7
revise appendix (code, trainer)
davisagli Sep 6, 2026
73fb054
fix
davisagli Sep 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,11 @@ jobs:
steps:
- uses: actions/checkout@v7

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v9.0.0

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -q -r requirements.txt -c constraints.txt
sudo snap install --edge vale

- name: Run tests with make test (includes clean and linkcheckbroken)
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ distclean: ## Clean docs build directory and Python virtual environment
cd $(DOCS_DIR) && rm -rf $(BUILDDIR)/

venv/bin/python: ## Set up training: Install requirements
python3 -m venv venv
uv venv --seed venv
venv/bin/python -m pip install --upgrade pip
venv/bin/pip install -r requirements.txt
@echo
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@
},
],
"logo": {
"text": "Plone Training 2025",
"text": "Plone Training 2026",
},
"navigation_with_keys": True,
"path_to_docs": "docs",
Expand Down
4 changes: 2 additions & 2 deletions docs/contributing/writing-docs-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ The following are frequently used snippets and examples.
##### Link to a Chapter or Page

```md
We created an add-on in the last chapter {doc}`/mastering-plone/volto_custom_addon`.
We created an add-on in the last chapter {doc}`/mastering-plone/add-ons`.
```

We created an add-on in the last chapter {doc}`/mastering-plone/volto_custom_addon`.
We created an add-on in the last chapter {doc}`/mastering-plone/add-ons`.


(writing-docs-guide-link-heading-label)=
Expand Down
Binary file added docs/mastering-plone/_static/addons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/mastering-plone/_static/behaviors_frontend.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/mastering-plone/_static/features_control_panel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/mastering-plone/_static/frontpage_volto_logged_in.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/mastering-plone/_static/instructions_plone_running.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 9 additions & 10 deletions docs/mastering-plone/about_mastering.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,44 @@ myst:
html_meta:
"description": "What to expect. Trainings on site. Training videos."
"property=og:description": "What to expect. Trainings on site. Training videos."
"property=og:title": "About Mastering Plone development"
"property=og:title": "About Mastering Plone Development"
"keywords": "Plone, training, develop"
---

(about-mastering-label)=

# About Mastering Plone development
# About Mastering Plone Development

The *Mastering Plone Development* training is both: an online training and a handout for on-site trainings.
The *Mastering Plone Development* training is both an online training and a handout for on-site trainings.
We address developers.
You are interested in best practice guides and want to learn the why and where, so read on!

## The beginning and the continuation

This training was initially started as a Plone Classic training and evolved now to a roundtrip on both: Plone backend, React frontend and the interplay between backend and frontend.
This training was initially started as a Plone Classic training and evolved now to a roundtrip including the Plone backend, the Plone Volto frontend, and the interplay between backend and frontend.

This training is published on [training.plone.org](https://training.plone.org/).

We update the training ongoing to teach the best practices.
We update the training over time to teach the best practices.
You are welcome to contribute and give feedback on [GitHub issues](https://github.com/plone/training/issues).

Thank you for reading and your charity with non-native English speakers / writers.
Thank you for reading and your charity with non-native English speakers and writers.


(about-upcoming-label)=

## Upcoming trainings

Next Plone Conference, usually in October.
Announced on [plone.org](https://plone.org)
The Mastering Plone Development training will be offered September 21-22, 2026 as part of the [2026 Plone Conference](https://2026.ploneconf.org) in Maastricht.

If you want to have an on-site training or want to attend a public training, please ask for trainings on [community.plone.org](https://community.plone.org) or one of the {ref}`trainers<about-trainers-label>`.
If you want to have an on-site training or want to attend a public training, please ask for trainings on [community.plone.org](https://community.plone.org) or contact one of the {ref}`trainers<about-trainers-label>`.


(video-label)=

## Watch the training video

At Ploneconf 2021 the Mastering Plone Development training has been recorded.
At Ploneconf 2021 the Mastering Plone Development training was recorded.
It's a shortened version of the training, given by Philip Bauer and Katja Süss.

[Part 1 – Mastering Plone Development Training](https://www.youtube-nocookie.com/embed/Jzuw3uWtzzI?privacy_mode=1)
Expand Down
164 changes: 92 additions & 72 deletions docs/mastering-plone/add-ons.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,37 @@ myst:
html_meta:
"description": "Extending Plone with features via existing backend add-ons"
"property=og:description": "Extending Plone with features via existing backend add-ons"
"property=og:title": "Extending Plone with add-on packages"
"property=og:title": "Extend Plone with add-on packages"
"keywords": "Plone, Volto, add-on, customizing"
---

(add-ons-label)=

# Extending Plone with add-on packages
# Extend Plone with add-on packages

```{card}
Backend chapter

For frontend add-ons see chapter {ref}`volto-addon-label`.
In this chapter you will learn how to select and install Plone add-ons.

The creation of a custom backend add-on is explained in {doc}`voting-story/index`
The creation of a custom add-on is explained in {doc}`voting-story/index`
```

````{card}

Check out `mastering-plone-project` at tag `initial`:

```shell
git checkout initial
```

The code at the end of the chapter:

```shell
git checkout addons
```

More info in {doc}`code`
````

Plone add-ons enrich the CMS by

Expand All @@ -29,28 +44,22 @@ Plone add-ons enrich the CMS by
- customizing the editor experience
- adding content assembling features for overview pages

Plone 6 knows two groups of add-ons: add-ons for Plone and such for the frontend Volto.
Plone has two groups of add-ons: add-ons for the Plone backend and add-ons for the frontend Volto.

Plone backend add-ons provide

- content types
- behaviors to enrich content types

Plone frontend add-ons provide

- new blocks
- variations and enhancements of blocks
- a theme to design the layout of a site
- components independent of blocks like a dropdown navigation

Both can be coupled, if a frontend feature depends on a new content type, a new behavior or any other change needed in data structure.
For example an add-on that has the goal to provide a bookmarking feature depends on a backend add-on that handles the storing of the bookmarks.

Have a look at the curated lists of add-ons:


[Awesome Plone: backend add-ons](https://github.com/collective/awesome-plone/blob/main/README.md)
[Awesome Volto: frontend add-ons](https://github.com/collective/awesome-volto/blob/main/README.md)

Both can be coupled, if a frontend feature depends on a new content type, a new behavior, or any other change needed in data structure.
For example, an add-on that has the goal to provide a bookmarking feature depends on a backend add-on that handles the storing of the bookmarks.


(add-ons-find-label)=
Expand All @@ -64,8 +73,8 @@ Here are some tips.

- Find candidates on PyPI, npm or GitHub:

- curated list of [backend add-ons](https://github.com/collective/awesome-plone/blob/main/README.md)
- curated list of [frontend add-ons](https://github.com/collective/awesome-volto#readme)
- curated list of [awesome backend add-ons](https://github.com/collective/awesome-plone/blob/main/README.md)
- curated list of [awesome frontend add-ons](https://github.com/collective/awesome-volto#readme)
- Python packages on PyPI: <https://pypi.org/search/?c=Framework+%3A%3A+Plone>
- Plone add-ons on GitHub: <https://github.com/collective>
- Plone core packages on GitHub: <https://github.com/plone>
Expand Down Expand Up @@ -93,93 +102,104 @@ Here are some tips.
- Either extend an existing add-on to fit your needs or create a new add-on that does exactly what you need.


(add-ons-installing-label)=
(add-ons-install-form-block-label)=

## Installing Plone add-ons
## Example: the form block add-on

We have two groups of add-ons: backend and frontend.
For our case study, it would be nice to have a contact form to send questions to the conference organizers.
We can use the [Plone form block add-on](https://github.com/plone/form-block) for this.

The training setup starts without any frontend add-on.
Later on we will add features via a frontend add-on.
See chapter {doc}`volto_addon` how to install a frontend add-on.
It is released in two packages:

The training setup starts with one backend add-on `ploneconf.site`.
Let's see how it is installed.
- [`plone.formblock`](https://pypi.org/project/plone.formblock/) is the backend add-on
- [`@plone/volto-form-block`](https://www.npmjs.com/package/@plone/volto-form-block) is the frontend add-on

We have to add both of these to our project.

### Making a backend add-on package available to Zope
## Install the backend add-on

First, we must make the add-on package available to Zope.
This means that Zope can import the code.
First, we must add the backend add-on as a dependency, so that its code will be available.

A backend add-on is a Python package.
Therefore we install it with pip.
Edit the file {file}`backend/pyproject.toml` and add `plone.formblock` to the `dependencies`:

Look at the {file}`requirements.txt` file.
You add a package to the configuration by adding a new line containing the package name.
```{code-block} toml
:linenos:
:emphasize-lines: 6

If the add-on is not released on [PyPI](https://pypi.org/), we tell Zope where to find the package on `Github` or another repository platform by including the necessary information in {file}`mx.ini`.

```ini
[training.votable]
url=git@github.com:collective/training.votable.git
branch=main
; tag=volto
dependencies = [
"Products.CMFPlone==6.2.1",
"plone.api",
"plone.restapi",
"plone.volto",
"plone.formblock==1.0.0a3",
]
```

Adding the package to {file}`instance.yaml` causes the generation of the Zope configuration to make the package available in a Zope app.

```yaml
zcml_package_includes: training.votable, ploneconf.site
```
It's a good idea to "pin" the add-on to a specific version, to make sure that it won't get accidentally upgraded when you don't expect it, if there is a new release of the add-on in the future.

Running `make build` has three effects:
- The build installs the python package with `pip`.
- The build generates in `instance/` a Zope instance configuration that makes the package available in our Zope app.
- As soon as the Zope app is started via `make start`, the add-on can be enabled per Plone instance.
A Zope app can include multiple Plone instances.
So an add-on can be enabled per Plone instance.
Now re-install the project with the new dependencies:

```{seealso}
Documentation {doc}`plone6docs:admin-guide/add-ons`
```shell
make backend-install
```

This runs `uv sync` which updates the Python virtual environment with the dependencies listed in `pyproject.toml`.
Now when the backend is restarted, the code for the add-on is available.

### Enabling add-ons in your Plone site

An add-on can be enabled per Plone instance.
Backend add-ons usually also need to be installed in a specific Plone site.

In your browser, go to `Site Setup` at `http://localhost:3000/controlpanel`, and open the `Add-ons` control panel. You will see a list of available add-ons.
In your browser, go to `Site Setup` at `http://localhost:3000/controlpanel`, and open the `Add-ons` control panel.
You will see a list of available add-ons.
Click to install the form block add-on.

````{card}
```{image} ../_static/site_setup.png
```{image} _static/addons.png
:alt: Plone `Add-ons` control panel, showing available configuration options
:target: ../_static/site_setup.png
```
+++
_Plone `Add-ons` control panel, showing available configuration options._
_Add-ons control panel, showing available configuration options._
````

Enable `ploneconf.site` now if you haven't done already.
```{seealso}
Documentation {doc}`plone6docs:admin-guide/add-ons`
```

This is what happens: The GenericSetup profile of the product gets loaded. This does things like:
## Install the frontend add-on

- Registering new content types
- Registering behaviors
- Configuring new actions
- Create catalog indexes
We also need to install the code for the frontend add-on.
Update the `addons` and `dependencies` in {file}`frontend/packages/volto-ploneconf-site/package.json`:

All this is configured in the default GenericSetup profile, which can be found in `backend/sources/<package name>/src/<package name>/profiles/default`.
In the next chapters we will add here our content type `talk`, configure a catalog index, and some more.
```{code-block} json
:emphasize-lines: 2, 5

"addons": [
"@plone/volto-form-block"
],
"dependencies": {
"@plone/volto-form-block": "^1.0.0-alpha.0",
},
```

(add-ons-summary-label)=
```{tip}
`dependencies` tells the package manager `pnpm` to install the code.
`addons` tells Volto to load the add-on's configuration.
```

## Summary
Now re-install the frontend with the new dependencies:

We have seen in short how to extend a vanilla Plone website with third party add-ons to add new functionality.
Even if you do not use many of these, they are nonetheless an inspiration on how to implement features in Plone.
```shell
make frontend-install
```

After you restart the frontend, you should be able to add a form block.

```{tip}
To confirm that the frontend add-on is installed, go to http://localhost:3000/controlpanel and look at the list of Add-ons at the bottom.
```

(add-ons-summary-label)=

## Summary

For frontend add-ons see chapter {ref}`volto-addon-label`
We have seen in short how to extend a vanilla Plone website with third party add-ons to add new functionality.
Even if you do not use many of these, they can be useful examples of how to implement features in Plone.
Loading