Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
cb242c3
Be more general about expected familiarity with Python packaging in o…
davisagli Mar 25, 2026
ee74297
Update conceptual-guides/package-management.md to cover more tools
davisagli Mar 25, 2026
7e9ee20
Add uv-based instructions to admin-guide/override-core.md, organize i…
davisagli Mar 25, 2026
89c347d
Apply suggestions from code review
davisagli Mar 26, 2026
cd84028
More updates from review
davisagli Mar 26, 2026
0f5e395
Fix formatting/warnings in glossary
davisagli Mar 26, 2026
43d90ef
Update conceptual-guides/make-backend-build.md
davisagli Mar 26, 2026
7bb05f9
Update admin-guide/add-ons.md
davisagli Mar 26, 2026
f919508
Revise after testing
davisagli Mar 26, 2026
31ac9dc
Extension of PR #2072
stevepiercy Mar 26, 2026
f8b392b
Added guilabel role, and reversed the order of instructions in increa…
stevepiercy Mar 26, 2026
a1ac3f9
The instructions for installation from PyPI for both uv and pip were …
stevepiercy Mar 26, 2026
72c0b9c
Move tip outside DRY, and combine both the original and new options. …
stevepiercy Mar 26, 2026
358fefc
- Move tip outside DRY, and combine both the original and new options…
stevepiercy Mar 26, 2026
bde905b
- Repeat for source installation the same DRY, split of configuration…
stevepiercy Mar 26, 2026
8ca912c
Merge pull request #2073 from plone/uv-managed-stevepiercy
davisagli Mar 26, 2026
4dd55dd
Several updates:
davisagli Mar 26, 2026
d650a08
Another revision of uv-managed branch (#2074)
stevepiercy Mar 27, 2026
16cd84f
Link to Python standard library
stevepiercy Mar 28, 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
145 changes: 119 additions & 26 deletions docs/admin-guide/override-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,26 @@ myst:
Plone includes a few hundred Python packages.
Sometimes you will need to override one or more package versions to fix a bug.

## Override the version of a core Plone package

## Cookieplone
For instructions of how to override a core Plone package, select the tab below according to your Python package manager.

Use the following instructions if you installed Plone with Cookieplone.
`````{tab-set}

````{tab-item} uv

### Override a core Plone package
```{tip}
Use the following instructions if you have a project that was created using Cookieplone after March 2026.
```

Add a version override to the file {file}`mx.ini`.
Edit `constraint-dependencies` in the file {file}`pyproject.toml`.
This example uses `plone.api`.

```
[settings]
version-overrides =
plone.api==2.0.0a3
```

```{seealso}
The {file}`mx.ini` file configures a tool called {term}`mxdev`.
For an explanation of why Plone uses `mxdev`, see {ref}`manage-backend-python-packages-label`.
[tool.uv]
constraint-dependencies = [
"plone.api==2.0.0a3",
]
```

Stop the backend with {kbd}`ctrl-c`.
Expand All @@ -50,19 +50,26 @@ Now restart the backend.
{doc}`run-plone`
```

````

### Install a core Plone package from source
````{tab-item} pip

You can also use `mxdev` to install core Plone packages from a source control system such as GitHub.
```{tip}
Use the following instructions if you have a project that was created using Cookieplone before March 2026.
```

Add the Plone package you want to check out in the file {file}`mx.ini`.
This example uses `plone.restapi`.
Add a version override to the file {file}`mx.ini`.
This example uses `plone.api`.

```cfg
[plone.restapi]
url = git@github.com:plone/plone.restapi.git
branch = main
extras = test
```
[settings]
version-overrides =
plone.api==2.0.0a3
```

```{seealso}
The {file}`mx.ini` file configures a tool called {term}`mxdev`.
For an explanation of why Plone uses `mxdev` for projects using pip as the Python package manager, see {ref}`manage-packages-mxdev-label`.
```

Stop the backend with {kbd}`ctrl-c`.
Expand All @@ -79,12 +86,13 @@ Now restart the backend.
{doc}`run-plone`
```

````

## Buildout
````{tab-item} Buildout

```{tip}
Use the following instructions if you installed Plone with Buildout.

### Override a core Plone package
```

Update the file {file}`buildout.cfg`.
This example uses `plone.api`.
Expand Down Expand Up @@ -115,7 +123,7 @@ The version pins specified in the `[versions]` section will take precedence over
To actually download and install the new package version, run the following command.

```shell
bin/buildout
bin/buildout -N
```

Then restart your instance.
Expand All @@ -124,11 +132,92 @@ Then restart your instance.
{doc}`run-plone`
```

````

`````

### Install a core Plone package from source
## Install a core Plone package from source

A core Plone package can be installed from a source control system such as GitHub.

Choose a tab depending on your Python package manager.

`````{tab-set}

````{tab-item} uv

```{tip}
Use the following instructions if you have a project that was created using Cookieplone after March 2026.
```

This example uses `plone.restapi`.

Clone the repository into a local directory.

```shell
git clone git@github.com:plone/plone.restapi.git
```

Add the local directory to your uv project as an editable package.

```shell
cd backend
uv add --editable ../plone.restapi
```

Stop the backend with {kbd}`ctrl-c`.

Now restart the backend.

```{seealso}
{doc}`run-plone`
```

````

````{tab-item} pip

```{tip}
Use the following instructions if you have a project that was created using Cookieplone before March 2026.
```

Add the Plone package you want to check out in the file {file}`mx.ini`.
This example uses `plone.restapi`.

```cfg
[plone.restapi]
url = git@github.com:plone/plone.restapi.git
branch = main
extras = test
```

```{seealso}
The {file}`mx.ini` file configures a tool called {term}`mxdev`.
For an explanation of why Plone uses `mxdev`, see {ref}`manage-packages-mxdev-label`.
```

Stop the backend with {kbd}`ctrl-c`.

To actually download and install the new package version, run the following command.

```shell
make backend-build
```

Now restart the backend.

```{seealso}
{doc}`run-plone`
```

````

````{tab-item} Buildout

```{tip}
Use the following instructions if you installed Plone with Buildout.
```

Update the file {file}`buildout.cfg`.
This example uses `plone.restapi`.

Expand Down Expand Up @@ -176,3 +265,7 @@ Then restart your instance.
```{seealso}
This approach uses the [`mr.developer`](https://pypi.org/project/mr.developer/) Buildout extension.
```

````

`````
63 changes: 49 additions & 14 deletions docs/conceptual-guides/package-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ myst:
"description": "Package management in Plone."
"property=og:description": "Package management in Plone."
"property=og:title": "Package management"
"keywords": "Plone 6, package management, mxdev"
"keywords": "Plone 6, package management, pip, uv, mxdev"
---

# Package management
Expand All @@ -24,23 +24,36 @@ Python itself has a complex and convoluted history with package management, as [
```


(manage-backend-python-packages-label)=

## Manage backend Python packages

If you want to check out a Plone core package for development, or want to override the constraints of Plone, normally you would define constraints with a file {file}`constraints.txt` to tell `pip` to install a different version of a Plone package.
### pip

By convention in the Python community, {term}`pip` is commonly used to install Python packages.
It is one supported way to install the Plone backend.

Each Plone version requires specific versions of many different packages.
So, pip should be used with constraints to make sure the correct versions are installed.
For example:

```text
# constraints.txt with unresolvable version conflict
-c https://dist.plone.org/release/6.0.9/constraints.txt
plone.api>=2.1.0
```shell
bin/pip install -c https://dist.plone.org/release/6.1-latest/constraints.txt Plone
```

Unfortunately `pip` does not allow overriding constraints this way.
{term}`mxdev` solves this issue.
In the Plone community, constraints are sometimes called "version pins."

As a best practice, pip should always be used inside a specific Python {term}`virtual environment` to keep the packages separate from other applications.

(manage-packages-mxdev-label)=

### `mxdev` to the rescue!
### mxdev

During development, it is sometimes necessary to override the Plone version constraints.
This makes it possible to:
- install a newer version of a core Plone package that was released with a bugfix
- install an unreleased core Plone package from a source control system

Unfortunately pip does not allow overriding constraints this way.
{term}`mxdev` solves this issue.

`mxdev` resolves Plone constraints according to your needs for pinning versions or source checkouts.
It reads its configuration file {file}`mx.ini`, and your {file}`requirements.txt` and {file}`constraints.txt` files.
Expand All @@ -56,9 +69,31 @@ You or your development tools, such as GNU Make, must perform that step.
{doc}`/admin-guide/add-ons`
```

### uv

More recently, {term}`uv` has become popular as a way to install Python packages.
This package manager is popular for its speed, its ability to manage the installation of Python itself, and its ability to consistently reproduce installed packages using a {file}`uv.lock` file.

When a project is fully managed using uv, it is configured in `pyproject.toml` and the packages are installed using `uv sync`.

uv also has a backwards-compatible mode which works more like pip, and installs packages into a virtual environment via the command `uv pip install`.

If you create a Plone project using Cookieplone, it creates a backend managed by uv.

### buildout

{term}`Buildout` is a tool for installing Python packages that has been used in the Plone community since about 2007, and is still preferred by some members of the community.

It not only installs packages, but can set up other things using an extensible system of "recipes."

Buildout does not install Python packages into a virtual environment.
Instead, it creates scripts that add the necessary packages to `sys.path` before running the script target.

## Manage frontend Node.js packages

```{todo}
Why do we use pnpm?
```
### pnpm

Plone uses {term}`pnpm` to install Node.js packages.

Compared to the standard {term}`npm`, it has features that help with developing multiple Node.js packages in the same workspace.
In Plone, this is used to manage the installation of your project add-on alongside Volto core and other add-ons.
16 changes: 16 additions & 0 deletions docs/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -964,4 +964,20 @@ Plate
[Plate](https://platejs.org/) is a {term}`Slate`-based editor, introduced in Seven.
Plate has a large community and provides a rich set of plugins to customize the editor experience.
Key features include the single page editor, as well as AI integration.

virtual environment
A virtual environment is an isolated Python environment with its own set of installed packages.
A virtual environment is created on top of an existing Python installation, known as the virtual environment's "base" Python, and by default is isolated from the packages in the base environment, so that only those explicitly installed in the virtual environment are available.

```seealso
- {term}`virtualenv`
- {term}`venv`
```

virtualenv
[`virtualenv`](https://virtualenv.pypa.io/en/latest/) is a tool to create isolated Python environments.
Since Python 3.3, a subset of it has been integrated into the standard library under the {term}`venv` module.

venv
The {doc}`venv` module in the Python standard library supports creating lightweight {term}`virtual environment`s, each with their own independent set of Python packages installed in their {doc}`site` directories.
```
3 changes: 1 addition & 2 deletions docs/overview/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ Our documentation contains setup examples for these services, yet requires that
One of the key benefits of the new React-based frontend for Plone 6 is that you can now customize and theme Plone extensively using HTML, CSS, and JavaScript using up-to-date frontend technologies without having to set up a local Python development environment.
The Plone backend can be run on a local developer machine in a container.

Basic familiarity with programming in Python and managing Python modules and packages using `virtualenv` and `pip` is required to work on the backend code.
We use `venv` and {term}`mxdev` to manage the source installation of packages in Plone 6.
Basic familiarity with programming in Python and managing Python modules and packages using {term}`pip` or {term}`uv` is required to work on the backend code.

Similarly, to develop for the new React frontend, you need to have some experience with setting up Node.js, using a tool like {term}`nvm` to isolate your setup, and familiarity with {term}`pnpm` and {term}`React`.

Expand Down