From cb242c34d41b10bc3d15759680087cdd08aa6216 Mon Sep 17 00:00:00 2001 From: David Glick Date: Wed, 25 Mar 2026 15:40:10 -0700 Subject: [PATCH 01/18] Be more general about expected familiarity with Python packaging in overview/index.md --- docs/overview/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/overview/index.md b/docs/overview/index.md index 5601a2e54..a6e9ddb78 100644 --- a/docs/overview/index.md +++ b/docs/overview/index.md @@ -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`. From ee74297d7791446da64b5b021cb77da549bd7317 Mon Sep 17 00:00:00 2001 From: David Glick Date: Wed, 25 Mar 2026 15:40:40 -0700 Subject: [PATCH 02/18] Update conceptual-guides/package-management.md to cover more tools --- docs/conceptual-guides/package-management.md | 58 ++++++++++++++++---- docs/glossary.md | 3 + 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/docs/conceptual-guides/package-management.md b/docs/conceptual-guides/package-management.md index 595c0637b..2ae46810a 100644 --- a/docs/conceptual-guides/package-management.md +++ b/docs/conceptual-guides/package-management.md @@ -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 @@ -28,19 +28,31 @@ Python itself has a complex and convoluted history with package management, as [ ## 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 -```text -# constraints.txt with unresolvable version conflict --c https://dist.plone.org/release/6.0.9/constraints.txt -plone.api>=2.1.0 +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: + +```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 {term}`virtualenv` to keep the packages separate from other applications. +### mxdev -### `mxdev` to the rescue! +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. @@ -56,9 +68,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 virtualenv using `uv pip install`. + +If you create a Plone project using Cookieplone, it creates a backend managed by `uv` (starting in March 2026). + +### 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 virtualenv. +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. diff --git a/docs/glossary.md b/docs/glossary.md index 45e1b9110..5e7a366e6 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -964,4 +964,7 @@ 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. + +virtualenv + A virtualenv is an isolated Python environment with its own set of installed packages. ``` From 7e9ee20c977aa3aa471d818f40b63caf5499d3d7 Mon Sep 17 00:00:00 2001 From: David Glick Date: Wed, 25 Mar 2026 16:15:48 -0700 Subject: [PATCH 03/18] Add uv-based instructions to admin-guide/override-core.md, organize in tabs --- docs/admin-guide/override-core.md | 145 +++++++++++++++---- docs/conceptual-guides/package-management.md | 4 +- 2 files changed, 121 insertions(+), 28 deletions(-) diff --git a/docs/admin-guide/override-core.md b/docs/admin-guide/override-core.md index 7fc64f739..791398b64 100644 --- a/docs/admin-guide/override-core.md +++ b/docs/admin-guide/override-core.md @@ -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 +Choose a tab depending on 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`. @@ -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`, see {ref}`manage-packages-mxdev-label`. ``` Stop the backend with {kbd}`ctrl-c`. @@ -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`. @@ -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. @@ -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`. @@ -176,3 +265,7 @@ Then restart your instance. ```{seealso} This approach uses the [`mr.developer`](https://pypi.org/project/mr.developer/) Buildout extension. ``` + +```` + +````` diff --git a/docs/conceptual-guides/package-management.md b/docs/conceptual-guides/package-management.md index 2ae46810a..96f9f164e 100644 --- a/docs/conceptual-guides/package-management.md +++ b/docs/conceptual-guides/package-management.md @@ -24,8 +24,6 @@ Python itself has a complex and convoluted history with package management, as [ ``` -(manage-backend-python-packages-label)= - ## Manage backend Python packages ### pip @@ -44,6 +42,8 @@ In the Plone community, constraints are sometimes called "version pins." As a best practice, pip should always be used inside a specific {term}`virtualenv` to keep the packages separate from other applications. +(manage-packages-mxdev-label)= + ### mxdev During development, it is sometimes necessary to override the Plone version constraints. From 89c347db1207a4e0295fe02af76a432a9ac5e490 Mon Sep 17 00:00:00 2001 From: David Glick Date: Wed, 25 Mar 2026 18:20:17 -0700 Subject: [PATCH 04/18] Apply suggestions from code review Co-authored-by: Steve Piercy --- docs/admin-guide/override-core.md | 6 +++--- docs/conceptual-guides/package-management.md | 17 +++++++++-------- docs/glossary.md | 15 ++++++++++++++- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/docs/admin-guide/override-core.md b/docs/admin-guide/override-core.md index 791398b64..0b2d60160 100644 --- a/docs/admin-guide/override-core.md +++ b/docs/admin-guide/override-core.md @@ -16,7 +16,7 @@ Sometimes you will need to override one or more package versions to fix a bug. ## Override the version of a core Plone package -Choose a tab depending on your Python package manager. +For instructions of how to override a core Plone package, select the tab below according to your Python package manager. `````{tab-set} @@ -69,7 +69,7 @@ version-overrides = ```{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`. +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`. @@ -158,7 +158,7 @@ Clone the repository into a local directory. git clone git@github.com:plone/plone.restapi.git ``` -Add the local directory to your `uv` project as an editable package. +Add the local directory to your uv project as an editable package. ```shell cd backend diff --git a/docs/conceptual-guides/package-management.md b/docs/conceptual-guides/package-management.md index 96f9f164e..05970a81b 100644 --- a/docs/conceptual-guides/package-management.md +++ b/docs/conceptual-guides/package-management.md @@ -28,7 +28,8 @@ Python itself has a complex and convoluted history with package management, as [ ### 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. +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. @@ -40,7 +41,7 @@ bin/pip install -c https://dist.plone.org/release/6.1-latest/constraints.txt Plo In the Plone community, constraints are sometimes called "version pins." -As a best practice, pip should always be used inside a specific {term}`virtualenv` to keep the packages separate from other applications. +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)= @@ -51,7 +52,7 @@ 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. +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. @@ -73,11 +74,11 @@ You or your development tools, such as GNU Make, must perform that step. 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`. +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 virtualenv using `uv pip install`. +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` (starting in March 2026). +If you create a Plone project using Cookieplone, it creates a backend managed by uv. ### buildout @@ -85,7 +86,7 @@ If you create a Plone project using Cookieplone, it creates a backend managed by 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 virtualenv. +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 @@ -94,5 +95,5 @@ Instead, it creates scripts that add the necessary packages to `sys.path` before 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. +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. diff --git a/docs/glossary.md b/docs/glossary.md index 5e7a366e6..056ffd744 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -965,6 +965,19 @@ Plate 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 - A virtualenv is an isolated Python environment with its own set of installed packages. + [`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. ``` From cd84028519885bb0ee59dc3a8f0a66a2c7d37948 Mon Sep 17 00:00:00 2001 From: David Glick Date: Wed, 25 Mar 2026 18:56:34 -0700 Subject: [PATCH 05/18] More updates from review --- docs/admin-guide/override-core.md | 36 ++++++++++--------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/docs/admin-guide/override-core.md b/docs/admin-guide/override-core.md index 0b2d60160..8201ed2f8 100644 --- a/docs/admin-guide/override-core.md +++ b/docs/admin-guide/override-core.md @@ -18,14 +18,15 @@ Sometimes you will need to override one or more package versions to fix a bug. For instructions of how to override a core Plone package, select the tab below according to your Python package manager. +```{tip} +Select the tab for uv if you have a project that was created using Cookieplone after March 19, 2026. +Select the tab for pip if you have a project that was created using Cookieplone earlier. +``` + `````{tab-set} ````{tab-item} uv -```{tip} -Use the following instructions if you have a project that was created using Cookieplone after March 2026. -``` - Edit `constraint-dependencies` in the file {file}`pyproject.toml`. This example uses `plone.api`. @@ -54,10 +55,6 @@ Now restart the backend. ````{tab-item} pip -```{tip} -Use the following instructions if you have a project that was created using Cookieplone before March 2026. -``` - Add a version override to the file {file}`mx.ini`. This example uses `plone.api`. @@ -90,10 +87,6 @@ Now restart the backend. ````{tab-item} Buildout -```{tip} -Use the following instructions if you installed Plone with Buildout. -``` - Update the file {file}`buildout.cfg`. This example uses `plone.api`. @@ -140,16 +133,17 @@ Then restart your instance. A core Plone package can be installed from a source control system such as GitHub. -Choose a tab depending on your Python package manager. +For instructions, select the tab below according to your Python package manager. + +```{tip} +Select the tab for uv if you have a project that was created using Cookieplone after March 19, 2026. +Select the tab for pip if you have a project that was created using Cookieplone earlier. +``` `````{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. @@ -177,10 +171,6 @@ Now restart the backend. ````{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`. @@ -214,10 +204,6 @@ Now restart the backend. ````{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`. From 0f5e395a5ec5252743d1ff4dd19e43974f0e14b6 Mon Sep 17 00:00:00 2001 From: David Glick Date: Wed, 25 Mar 2026 18:56:44 -0700 Subject: [PATCH 06/18] Fix formatting/warnings in glossary --- docs/glossary.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/glossary.md b/docs/glossary.md index 056ffd744..d6ac505ab 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -88,7 +88,7 @@ NFS [Network File System](https://en.wikipedia.org/wiki/Network_File_System). -NPM +npm npm is a package manager for the JavaScript programming language. It is the default package manager for the JavaScript runtime environment Node.js. Also a registry of JavaScript packages, similar to PyPI. @@ -969,7 +969,7 @@ 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 + ```{seealso} - {term}`virtualenv` - {term}`venv` ``` @@ -979,5 +979,5 @@ virtualenv 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. + The `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 {file}`site-packages` directories. ``` From 43d90effd6363f8cbee683a302d9ca781f1a2060 Mon Sep 17 00:00:00 2001 From: David Glick Date: Wed, 25 Mar 2026 19:09:37 -0700 Subject: [PATCH 07/18] Update conceptual-guides/make-backend-build.md --- docs/conceptual-guides/make-backend-build.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/conceptual-guides/make-backend-build.md b/docs/conceptual-guides/make-backend-build.md index a51a932ff..bdb084ae7 100644 --- a/docs/conceptual-guides/make-backend-build.md +++ b/docs/conceptual-guides/make-backend-build.md @@ -18,8 +18,8 @@ The `Makefile` at the root of your project invokes commands in `backend/Makefile The command `make backend-build` performs the following tasks. - Invokes the target `install` in `backend/Makefile`. -- `install` has the two dependencies `$(VENV_FOLDER)` and `config`. -- `$(VENV_FOLDER)` creates and populates a virtual Python environment with uv from a {file}`constraints.txt` file generated using mxdev. -- `config` creates the Zope and Plone configuration files using cookiecutter-zope-instance. +- `install` has the two dependencies `sync` and `config`. +- `sync` runs `uv sync` to install the project as defined in {file}`pyproject.toml`. +- `config` creates the Zope and Plone configuration files using {term}`cookiecutter-zope-instance`. You can configure your Zope instance as described in the section {doc}`/admin-guide/configure-zope`. From 7bb05f9239154267ffba80afc72772c2c1837a9d Mon Sep 17 00:00:00 2001 From: David Glick Date: Wed, 25 Mar 2026 19:37:26 -0700 Subject: [PATCH 08/18] Update admin-guide/add-ons.md --- docs/admin-guide/add-ons.md | 165 +++++++++++++++++------------------- docs/glossary.md | 3 + 2 files changed, 83 insertions(+), 85 deletions(-) diff --git a/docs/admin-guide/add-ons.md b/docs/admin-guide/add-ons.md index d2f0c7e73..cf8d6e375 100644 --- a/docs/admin-guide/add-ons.md +++ b/docs/admin-guide/add-ons.md @@ -18,13 +18,17 @@ The Volto frontend has its own system of add-ons using Node.js packages. See {doc}`/volto/development/add-ons/index`. ``` +## Install an add-on from PyPI -## Cookieplone +For instructions to install an add-on that is released on {term}`PyPI`, select the tab below according to your Python package manager. -Use the following instructions if you installed Plone with Cookieplone. +```{tip} +Select the tab for uv if you have a project that was created using Cookieplone. +``` +`````{tab-set} -### Install an add-on +````{tab-item} uv Add the name of your add-on in the file {file}`backend/pyproject.toml` in the section `dependencies`. This example adds [`collective.easyform`](https://pypi.org/project/collective.easyform/). @@ -59,66 +63,47 @@ To actually download and install the new add-on, run the following command. make backend-build ``` -Now restart the backend. - -```{seealso} -{doc}`run-plone` -``` - -In your web browser, and assuming you are currently logged in as an administrator, visit the URL http://localhost:8080/Plone/prefs_install_products_form. - -Then click the {guilabel}`Install` button next to your add-on to complete installation of the add-on. - -Some add-ons have configuration options. -To configure such add-ons, return to the {guilabel}`Site Setup` control panel. -At the bottom of the page, you should see the heading {guilabel}`Add-on Configuration`, and a control panel to configure the add-on that you just installed. +```` +````{tab-item} Buildout -### Install an add-on from source - -An add-on can be installed from a source control system such as GitHub. - -Add a line with the name of your add-on in the file {file}`backend/requirements.txt`. +Update the file {file}`buildout.cfg`. This example uses [`collective.easyform`](https://pypi.org/project/collective.easyform/). -``` -collective.easyform -``` - -```{note} -When installing an add-on from source, it's best not to pin a version. -This way you always get the version that's currently available in the source control system. -``` - -Next add the add-on to `zcml_package_includes` in the file {file}`backend/instance.yaml` so that its configuration will load. +```cfg +[buildout] +extends = + https://dist.plone.org/release/6-latest/versions.cfg -```yaml -default_context: - zcml_package_includes: project_title, collective.easyform -``` +parts = + instance -Finally, add the package's source to the file {file}`mx.ini`. +[instance] +recipe = plone.recipe.zope2instance +user = admin:admin +http-address = 8080 +eggs = + Plone + collective.easyform -```cfg -[collective.easyform] -url=git@github.com:collective/collective.easyform.git -branch=dev-branch-name -extras=test +[versions] +collective.easyform = 4.2.1 ``` -```{seealso} -The {file}`mx.ini` file configures a tool called {term}`mxdev`. -See the [documentation of `mxdev` in its README.md](https://github.com/mxstack/mxdev/blob/main/README.md) for complete information. +```{tip} +Including the add-on version, or "pinning a version", ensures that it won't unintentionally get upgraded in the future. ``` -Stop the backend with {kbd}`ctrl-c`. - To actually download and install the new add-on, run the following command. ```shell -make backend-build +bin/buildout -N ``` +```` + +````` + Now restart the backend. ```{seealso} @@ -126,60 +111,58 @@ Now restart the backend. ``` In your web browser, and assuming you are currently logged in as an administrator, visit the URL http://localhost:8080/Plone/prefs_install_products_form. -An upgrade step might need to be performed in the Plone control panel. -Follow the upgrade information, if present. -Else click the {guilabel}`Install` button to complete installation of the add-on. +Then click the {guilabel}`Install` button next to your add-on to complete installation of the add-on. + +Some add-ons have configuration options. +To configure such add-ons, return to the {guilabel}`Site Setup` control panel. +At the bottom of the page, you should see the heading {guilabel}`Add-on Configuration`, and a control panel to configure the add-on that you just installed. -## Buildout -Use the following instructions if you installed Plone with Buildout. +## Install an add-on from source -### Install an add-on +An unreleased add-on can be installed from a source control system such as GitHub. -Update the file {file}`buildout.cfg`. -This example uses [`collective.easyform`](https://pypi.org/project/collective.easyform/). +For instructions to install an add-on that is released on {term}`PyPI`, select the tab below according to your Python package manager. -```cfg -[buildout] -extends = - https://dist.plone.org/release/6-latest/versions.cfg +```{tip} +Select the tab for uv if you have a project that was created using Cookieplone. +``` -parts = - instance +`````{tab-set} -[instance] -recipe = plone.recipe.zope2instance -user = admin:admin -http-address = 8080 -eggs = - Plone - collective.easyform +````{tab-item} uv -[versions] -collective.easyform = 4.2.1 -``` +Clone the repository into a local directory. +This example uses [`collective.easyform`](https://pypi.org/project/collective.easyform/). -```{tip} -Including the add-on version, or "pinning a version", ensures that it won't unintentionally get upgraded in the future. +```shell +git clone git@github.com:collective/collective.easyform.git ``` -To actually download and install the new add-on, run the following command. +Add the local directory to your uv project as an editable package. ```shell -bin/buildout +cd backend +uv add --editable ../collective.easyform ``` -Then restart your instance. - -```{seealso} -{doc}`run-plone` +```{note} +When installing an add-on from source, it's best not to pin a version. +This way you always get the version that's currently available in the source control system. ``` +Next add the add-on to `zcml_package_includes` in the file {file}`backend/instance.yaml` so that its configuration will load. -### Install an add-on from source +```yaml +default_context: + zcml_package_includes: project_title, collective.easyform +``` + +Stop the backend with {kbd}`ctrl-c`. +```` -You can install an add-on from a source control system such as GitHub. +````{tab-item} Buildout Update the file {file}`buildout.cfg`. This example uses [`collective.easyform`](https://pypi.org/project/collective.easyform/). @@ -213,12 +196,24 @@ To actually download and install the new add-on, run the following command. bin/buildout ``` -Then restart your instance. - ```{seealso} -{doc}`run-plone` +This approach uses the [`mr.developer`](https://pypi.org/project/mr.developer/) Buildout extension. ``` +```` + +````` + +Now restart the backend. + ```{seealso} -This approach uses the [`mr.developer`](https://pypi.org/project/mr.developer/) Buildout extension. +{doc}`run-plone` ``` + +In your web browser, and assuming you are currently logged in as an administrator, visit the URL http://localhost:8080/Plone/prefs_install_products_form. + +Then click the {guilabel}`Install` button next to your add-on to complete installation of the add-on. + +Some add-ons have configuration options. +To configure such add-ons, return to the {guilabel}`Site Setup` control panel. +At the bottom of the page, you should see the heading {guilabel}`Add-on Configuration`, and a control panel to configure the add-on that you just installed. diff --git a/docs/glossary.md b/docs/glossary.md index d6ac505ab..2652cb377 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -104,6 +104,9 @@ pyenv Python version management. [pyenv](https://github.com/pyenv/pyenv) lets you easily switch between multiple versions of Python. +PyPI + The [Python Package Index](https://pypi.org/) is a repository of software for the Python programming language. + uv [uv](https://docs.astral.sh/uv/) is a Python package and project manager, written in Rust. From f9195081e4d01beed38360108c7d8bfa1b9bf578 Mon Sep 17 00:00:00 2001 From: David Glick Date: Wed, 25 Mar 2026 20:05:46 -0700 Subject: [PATCH 09/18] Revise after testing --- docs/admin-guide/add-ons.md | 95 ++++++++++++++++++++++++++++++- docs/admin-guide/override-core.md | 8 +-- 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/docs/admin-guide/add-ons.md b/docs/admin-guide/add-ons.md index cf8d6e375..a0411bdcf 100644 --- a/docs/admin-guide/add-ons.md +++ b/docs/admin-guide/add-ons.md @@ -23,7 +23,8 @@ See {doc}`/volto/development/add-ons/index`. For instructions to install an add-on that is released on {term}`PyPI`, select the tab below according to your Python package manager. ```{tip} -Select the tab for uv if you have a project that was created using Cookieplone. +Select the tab for uv if you have a project that was created using Cookieplone, and you have `managed = true` set in the `[tool.uv]` section of the file {file}`backend/pyproject.toml`. +Select the tab for pip if you have a project that was created using Cookieplone that does not have this setting. ``` `````{tab-set} @@ -65,6 +66,43 @@ make backend-build ```` +````{tab-item} pip + +Add the name of your add-on in the file {file}`backend/pyproject.toml` in the section `dependencies`. +This example adds [`collective.easyform`](https://pypi.org/project/collective.easyform/). + +```{code-block} toml +:emphasize-lines: 6 +dependencies = [ + "Products.CMFPlone==6.1.1", + "plone.api", + "plone.classicui", + "plone.app.caching", + "collective.easyform==4.4.0", +] +``` + +```{tip} +Including the add-on version, or "pinning a version", ensures that it won't unintentionally get upgraded in the future. +``` + +Also add the add-on to `zcml_package_includes` in the file {file}`backend/instance.yaml` to make sure its configuration will be loaded. + +```yaml +default_context: + zcml_package_includes: project_title, collective.easyform +``` + +Stop the backend with {kbd}`ctrl-c`. + +To actually download and install the new add-on, run the following command. + +```shell +make backend-build +``` + +```` + ````{tab-item} Buildout Update the file {file}`buildout.cfg`. @@ -126,7 +164,8 @@ An unreleased add-on can be installed from a source control system such as GitHu For instructions to install an add-on that is released on {term}`PyPI`, select the tab below according to your Python package manager. ```{tip} -Select the tab for uv if you have a project that was created using Cookieplone. +Select the tab for uv if you have a project that was created using Cookieplone, and you have `managed = true` set in the `[tool.uv]` section of the file {file}`backend/pyproject.toml`. +Select the tab for pip if you have a project that was created using Cookieplone that does not have this setting. ``` `````{tab-set} @@ -162,6 +201,58 @@ default_context: Stop the backend with {kbd}`ctrl-c`. ```` +````{tab-item} pip + +Add the name of your add-on in the file {file}`backend/pyproject.toml` in the section `dependencies`. +This example adds [`collective.easyform`](https://pypi.org/project/collective.easyform/). + +```{code-block} toml +:emphasize-lines: 6 +dependencies = [ + "Products.CMFPlone==6.1.1", + "plone.api", + "plone.classicui", + "plone.app.caching", + "collective.easyform", +] +``` + +```{note} +When installing an add-on from source, it's best not to pin a version. +This way you always get the version that's currently available in the source control system. +``` + +Next add the add-on to `zcml_package_includes` in the file {file}`backend/instance.yaml` so that its configuration will load. + +```yaml +default_context: + zcml_package_includes: project_title, collective.easyform +``` + +Finally, add the package's source to the file {file}`mx.ini`. + +```cfg +[collective.easyform] +url=git@github.com:collective/collective.easyform.git +branch=dev-branch-name +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 add-on, run the following command. + +```shell +make backend-build +``` + +```` + ````{tab-item} Buildout Update the file {file}`buildout.cfg`. diff --git a/docs/admin-guide/override-core.md b/docs/admin-guide/override-core.md index 8201ed2f8..0d0004cbb 100644 --- a/docs/admin-guide/override-core.md +++ b/docs/admin-guide/override-core.md @@ -19,8 +19,8 @@ Sometimes you will need to override one or more package versions to fix a bug. For instructions of how to override a core Plone package, select the tab below according to your Python package manager. ```{tip} -Select the tab for uv if you have a project that was created using Cookieplone after March 19, 2026. -Select the tab for pip if you have a project that was created using Cookieplone earlier. +Select the tab for uv if you have a project that was created using Cookieplone, and you have `managed = true` set in the `[tool.uv]` section of the file {file}`backend/pyproject.toml`. +Select the tab for pip if you have a project that was created using Cookieplone that does not have this setting. ``` `````{tab-set} @@ -136,8 +136,8 @@ A core Plone package can be installed from a source control system such as GitHu For instructions, select the tab below according to your Python package manager. ```{tip} -Select the tab for uv if you have a project that was created using Cookieplone after March 19, 2026. -Select the tab for pip if you have a project that was created using Cookieplone earlier. +Select the tab for uv if you have a project that was created using Cookieplone, and you have `managed = true` set in the `[tool.uv]` section of the file {file}`backend/pyproject.toml`. +Select the tab for pip if you have a project that was created using Cookieplone that does not have this setting. ``` `````{tab-set} From 31ac9dc8c3d94526b60228cb01fba315c23c9705 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 26 Mar 2026 00:57:14 -0700 Subject: [PATCH 10/18] Extension of PR #2072 - Break steps into subheadings, starting with configure the add-on installation --- docs/admin-guide/add-ons.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/admin-guide/add-ons.md b/docs/admin-guide/add-ons.md index a0411bdcf..664e9b1c8 100644 --- a/docs/admin-guide/add-ons.md +++ b/docs/admin-guide/add-ons.md @@ -20,7 +20,13 @@ See {doc}`/volto/development/add-ons/index`. ## Install an add-on from PyPI -For instructions to install an add-on that is released on {term}`PyPI`, select the tab below according to your Python package manager. +This section describes how to install an add-on that is released on {term}`PyPI` + + +### Configure add-on installation + +First, configure your project according to the instructions in the tabbed interface below. +Select the tab according to your Python package manager. ```{tip} Select the tab for uv if you have a project that was created using Cookieplone, and you have `managed = true` set in the `[tool.uv]` section of the file {file}`backend/pyproject.toml`. From f8b392b8d6f5727acdd940bccf35a129d3801b81 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 26 Mar 2026 00:59:28 -0700 Subject: [PATCH 11/18] Added guilabel role, and reversed the order of instructions in increasing specificity. --- docs/admin-guide/add-ons.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/admin-guide/add-ons.md b/docs/admin-guide/add-ons.md index 664e9b1c8..4b8756067 100644 --- a/docs/admin-guide/add-ons.md +++ b/docs/admin-guide/add-ons.md @@ -29,8 +29,8 @@ First, configure your project according to the instructions in the tabbed interf Select the tab according to your Python package manager. ```{tip} -Select the tab for uv if you have a project that was created using Cookieplone, and you have `managed = true` set in the `[tool.uv]` section of the file {file}`backend/pyproject.toml`. -Select the tab for pip if you have a project that was created using Cookieplone that does not have this setting. +Select the tab {guilabel}`uv` for projects created with Cookieplone which have in the file {file}`backend/pyproject.toml`, under the `[tool.uv]` table, the setting of `managed = true`. +Select the tab {guilabel}`pip` for projects created with Cookieplone that don't have this setting. ``` `````{tab-set} From a1ac3f9e9c6451de94412153b1b06bc18cd3c0f9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 26 Mar 2026 01:19:32 -0700 Subject: [PATCH 12/18] The instructions for installation from PyPI for both uv and pip were identical. Combine into the project creation method instead. --- docs/admin-guide/add-ons.md | 56 +++++-------------------------------- 1 file changed, 7 insertions(+), 49 deletions(-) diff --git a/docs/admin-guide/add-ons.md b/docs/admin-guide/add-ons.md index 4b8756067..a7a71bb58 100644 --- a/docs/admin-guide/add-ons.md +++ b/docs/admin-guide/add-ons.md @@ -20,59 +20,17 @@ See {doc}`/volto/development/add-ons/index`. ## Install an add-on from PyPI -This section describes how to install an add-on that is released on {term}`PyPI` +This section describes how to install an add-on that is released on {term}`PyPI`. ### Configure add-on installation First, configure your project according to the instructions in the tabbed interface below. -Select the tab according to your Python package manager. - -```{tip} -Select the tab {guilabel}`uv` for projects created with Cookieplone which have in the file {file}`backend/pyproject.toml`, under the `[tool.uv]` table, the setting of `managed = true`. -Select the tab {guilabel}`pip` for projects created with Cookieplone that don't have this setting. -``` +Select the tab according to the method you used to create your project. `````{tab-set} -````{tab-item} uv - -Add the name of your add-on in the file {file}`backend/pyproject.toml` in the section `dependencies`. -This example adds [`collective.easyform`](https://pypi.org/project/collective.easyform/). - -```{code-block} toml -:emphasize-lines: 6 -dependencies = [ - "Products.CMFPlone==6.1.1", - "plone.api", - "plone.classicui", - "plone.app.caching", - "collective.easyform==4.4.0", -] -``` - -```{tip} -Including the add-on version, or "pinning a version", ensures that it won't unintentionally get upgraded in the future. -``` - -Also add the add-on to `zcml_package_includes` in the file {file}`backend/instance.yaml` to make sure its configuration will be loaded. - -```yaml -default_context: - zcml_package_includes: project_title, collective.easyform -``` - -Stop the backend with {kbd}`ctrl-c`. - -To actually download and install the new add-on, run the following command. - -```shell -make backend-build -``` - -```` - -````{tab-item} pip +````{tab-item} Cookieplone Add the name of your add-on in the file {file}`backend/pyproject.toml` in the section `dependencies`. This example adds [`collective.easyform`](https://pypi.org/project/collective.easyform/). @@ -80,11 +38,11 @@ This example adds [`collective.easyform`](https://pypi.org/project/collective.ea ```{code-block} toml :emphasize-lines: 6 dependencies = [ - "Products.CMFPlone==6.1.1", + "Products.CMFPlone==6.1.4", "plone.api", "plone.classicui", "plone.app.caching", - "collective.easyform==4.4.0", + "collective.easyform==4.5.1", ] ``` @@ -215,11 +173,11 @@ This example adds [`collective.easyform`](https://pypi.org/project/collective.ea ```{code-block} toml :emphasize-lines: 6 dependencies = [ - "Products.CMFPlone==6.1.1", + "Products.CMFPlone==6.1.4", "plone.api", "plone.classicui", "plone.app.caching", - "collective.easyform", + "collective.easyform==4.5.1", ] ``` From 72c0b9c5fc9af1d69dff6f5df14d3766789d143e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 26 Mar 2026 01:23:05 -0700 Subject: [PATCH 13/18] Move tip outside DRY, and combine both the original and new options. Its target audience is first-timers. --- docs/admin-guide/add-ons.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/admin-guide/add-ons.md b/docs/admin-guide/add-ons.md index a7a71bb58..ab364d097 100644 --- a/docs/admin-guide/add-ons.md +++ b/docs/admin-guide/add-ons.md @@ -46,10 +46,6 @@ dependencies = [ ] ``` -```{tip} -Including the add-on version, or "pinning a version", ensures that it won't unintentionally get upgraded in the future. -``` - Also add the add-on to `zcml_package_includes` in the file {file}`backend/instance.yaml` to make sure its configuration will be loaded. ```yaml @@ -92,10 +88,6 @@ eggs = collective.easyform = 4.2.1 ``` -```{tip} -Including the add-on version, or "pinning a version", ensures that it won't unintentionally get upgraded in the future. -``` - To actually download and install the new add-on, run the following command. ```shell @@ -106,6 +98,13 @@ bin/buildout -N ````` +```{tip} +You can control which version of an add-on to install through "version pinning." + +- Specify the add-on version to avoid its unintentional upgrade. +- Leave it off to always install the latest version. +``` + Now restart the backend. ```{seealso} From 358fefc21d869e6a9e3129c8d47c7555d04cacf7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 26 Mar 2026 01:32:25 -0700 Subject: [PATCH 14/18] - Move tip outside DRY, and combine both the original and new options. Its target audience is first-timers. - Create new subsection for installation of the add-on. - Sync tabs. --- docs/admin-guide/add-ons.md | 50 +++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/docs/admin-guide/add-ons.md b/docs/admin-guide/add-ons.md index ab364d097..dae68edde 100644 --- a/docs/admin-guide/add-ons.md +++ b/docs/admin-guide/add-ons.md @@ -29,8 +29,8 @@ First, configure your project according to the instructions in the tabbed interf Select the tab according to the method you used to create your project. `````{tab-set} - ````{tab-item} Cookieplone +:sync: cookieplone Add the name of your add-on in the file {file}`backend/pyproject.toml` in the section `dependencies`. This example adds [`collective.easyform`](https://pypi.org/project/collective.easyform/). @@ -46,24 +46,16 @@ dependencies = [ ] ``` -Also add the add-on to `zcml_package_includes` in the file {file}`backend/instance.yaml` to make sure its configuration will be loaded. +To configure the add-on to load, in the file {file}`backend/instance.yaml`, under the key `default_context`, for the key `zcml_package_includes`, set its value to the add-on's name. ```yaml default_context: zcml_package_includes: project_title, collective.easyform ``` - -Stop the backend with {kbd}`ctrl-c`. - -To actually download and install the new add-on, run the following command. - -```shell -make backend-build -``` - ```` ````{tab-item} Buildout +:sync: buildout Update the file {file}`buildout.cfg`. This example uses [`collective.easyform`](https://pypi.org/project/collective.easyform/). @@ -85,17 +77,9 @@ eggs = collective.easyform [versions] -collective.easyform = 4.2.1 +collective.easyform = 4.5.1 ``` - -To actually download and install the new add-on, run the following command. - -```shell -bin/buildout -N -``` - ```` - ````` ```{tip} @@ -105,7 +89,31 @@ You can control which version of an add-on to install through "version pinning." - Leave it off to always install the latest version. ``` -Now restart the backend. +### Install the add-on + +Stop the backend with {kbd}`ctrl-c`. + +To actually download and install the new add-on, run the following command. + +`````{tab-set} +````{tab-item} Cookieplone +:sync: cookieplone + +```shell +make backend-build +``` +```` + +````{tab-item} Buildout +:sync: buildout + +```shell +bin/buildout -N +``` +```` +````` + +Finally, restart the backend. ```{seealso} {doc}`run-plone` From bde905b1d6d56a41e87c3fa76fbe357f65a95011 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 26 Mar 2026 02:06:37 -0700 Subject: [PATCH 15/18] - Repeat for source installation the same DRY, split of configuration and installation, and sync tabs as that for PyPI installation --- docs/admin-guide/add-ons.md | 95 ++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 34 deletions(-) diff --git a/docs/admin-guide/add-ons.md b/docs/admin-guide/add-ons.md index dae68edde..e010b7475 100644 --- a/docs/admin-guide/add-ons.md +++ b/docs/admin-guide/add-ons.md @@ -18,11 +18,15 @@ The Volto frontend has its own system of add-ons using Node.js packages. See {doc}`/volto/development/add-ons/index`. ``` +(install-an-add-on-from-pypi-label)= + ## Install an add-on from PyPI This section describes how to install an add-on that is released on {term}`PyPI`. +(configure-add-on-installation-pypi-label)= + ### Configure add-on installation First, configure your project according to the instructions in the tabbed interface below. @@ -89,6 +93,9 @@ You can control which version of an add-on to install through "version pinning." - Leave it off to always install the latest version. ``` + +(install-the-add-on-pypi-label)= + ### Install the add-on Stop the backend with {kbd}`ctrl-c`. @@ -113,7 +120,7 @@ bin/buildout -N ```` ````` -Finally, restart the backend. +Next, restart the backend. ```{seealso} {doc}`run-plone` @@ -130,18 +137,26 @@ At the bottom of the page, you should see the heading {guilabel}`Add-on Configur ## Install an add-on from source -An unreleased add-on can be installed from a source control system such as GitHub. +This section describes how to install an unreleased add-on from a source control system, such as GitHub. + -For instructions to install an add-on that is released on {term}`PyPI`, select the tab below according to your Python package manager. +(configure-add-on-installation-source-label)= + +### Configure add-on installation + +First, configure your project according to the instructions in the tabbed interface below. +Select the tab according to your Python package manager. ```{tip} -Select the tab for uv if you have a project that was created using Cookieplone, and you have `managed = true` set in the `[tool.uv]` section of the file {file}`backend/pyproject.toml`. -Select the tab for pip if you have a project that was created using Cookieplone that does not have this setting. +For projects created with Cookieplone, select either the tab labeled: + +- {guilabel}`uv` if the file {file}`backend/pyproject.toml`, under the table `[tool.uv]` has the setting of `managed = true` +- {guilabel}`pip` if your project doesn't have this setting ``` `````{tab-set} - ````{tab-item} uv +:sync: uv Clone the repository into a local directory. This example uses [`collective.easyform`](https://pypi.org/project/collective.easyform/). @@ -157,22 +172,16 @@ cd backend uv add --editable ../collective.easyform ``` -```{note} -When installing an add-on from source, it's best not to pin a version. -This way you always get the version that's currently available in the source control system. -``` - -Next add the add-on to `zcml_package_includes` in the file {file}`backend/instance.yaml` so that its configuration will load. +To configure the add-on to load, in the file {file}`backend/instance.yaml`, under the key `default_context`, for the key `zcml_package_includes`, set its value to the add-on's name. ```yaml default_context: zcml_package_includes: project_title, collective.easyform ``` - -Stop the backend with {kbd}`ctrl-c`. ```` ````{tab-item} pip +:sync: pip Add the name of your add-on in the file {file}`backend/pyproject.toml` in the section `dependencies`. This example adds [`collective.easyform`](https://pypi.org/project/collective.easyform/). @@ -184,16 +193,11 @@ dependencies = [ "plone.api", "plone.classicui", "plone.app.caching", - "collective.easyform==4.5.1", + "collective.easyform", ] ``` -```{note} -When installing an add-on from source, it's best not to pin a version. -This way you always get the version that's currently available in the source control system. -``` - -Next add the add-on to `zcml_package_includes` in the file {file}`backend/instance.yaml` so that its configuration will load. +To configure the add-on to load, in the file {file}`backend/instance.yaml`, under the key `default_context`, for the key `zcml_package_includes`, set its value to the add-on's name. ```yaml default_context: @@ -213,18 +217,10 @@ extras=test 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 add-on, run the following command. - -```shell -make backend-build -``` - ```` ````{tab-item} Buildout +:sync: buildout Update the file {file}`buildout.cfg`. This example uses [`collective.easyform`](https://pypi.org/project/collective.easyform/). @@ -251,22 +247,53 @@ eggs = [sources] collective.easyform = git https://github.com/collective/collective.easyform.git ``` +```` +````` + +```{tip} +When installing an add-on from source, it's best not to pin a version. +This way you always get the version that's currently available in the source control system. +``` + + +(install-the-add-on-source-label)= + +### Install the add-on + +Stop the backend with {kbd}`ctrl-c`. To actually download and install the new add-on, run the following command. +`````{tab-set} +````{tab-item} uv +:sync: uv + ```shell -bin/buildout +make backend-build ``` +```` + +````{tab-item} pip +:sync: pip + +```shell +make backend-build +``` +```` +````{tab-item} Buildout +:sync: buildout + +```shell +bin/buildout +``` ```{seealso} This approach uses the [`mr.developer`](https://pypi.org/project/mr.developer/) Buildout extension. ``` - ```` - ````` -Now restart the backend. +Next, restart the backend. ```{seealso} {doc}`run-plone` From 4dd55dd564d31e33dcc0768b3a57eb37536ced9b Mon Sep 17 00:00:00 2001 From: David Glick Date: Thu, 26 Mar 2026 11:07:41 -0700 Subject: [PATCH 16/18] Several updates: - Update override-core.md to follow the improvements in add-ons.md - Factor out the instructions for restarting the instance into _inc/_build-and-restart.md - Use a simpler check for whether it's a uv-managed Cookieplone project or not --- docs/_inc/_build-and-restart.md | 35 +++++++++ docs/admin-guide/add-ons.md | 76 +++--------------- docs/admin-guide/override-core.md | 125 ++++++++++-------------------- 3 files changed, 88 insertions(+), 148 deletions(-) create mode 100644 docs/_inc/_build-and-restart.md diff --git a/docs/_inc/_build-and-restart.md b/docs/_inc/_build-and-restart.md new file mode 100644 index 000000000..9a909bbab --- /dev/null +++ b/docs/_inc/_build-and-restart.md @@ -0,0 +1,35 @@ +If the backend is running, stop it with {kbd}`ctrl-c`. + +To actually download and install the package, run the following command. + +`````{tab-set} +````{tab-item} uv +:sync: uv + +```shell +make backend-build +``` +```` + +````{tab-item} pip +:sync: pip + +```shell +make backend-build +``` +```` + +````{tab-item} Buildout +:sync: buildout + +```shell +bin/buildout -N +``` +```` +````` + +Next, restart the backend. + +```{seealso} +{doc}`run-plone` +``` diff --git a/docs/admin-guide/add-ons.md b/docs/admin-guide/add-ons.md index e010b7475..95f46d798 100644 --- a/docs/admin-guide/add-ons.md +++ b/docs/admin-guide/add-ons.md @@ -98,32 +98,7 @@ You can control which version of an add-on to install through "version pinning." ### Install the add-on -Stop the backend with {kbd}`ctrl-c`. - -To actually download and install the new add-on, run the following command. - -`````{tab-set} -````{tab-item} Cookieplone -:sync: cookieplone - -```shell -make backend-build -``` -```` - -````{tab-item} Buildout -:sync: buildout - -```shell -bin/buildout -N -``` -```` -````` - -Next, restart the backend. - -```{seealso} -{doc}`run-plone` +```{include} /_inc/_build-and-restart.md ``` In your web browser, and assuming you are currently logged in as an administrator, visit the URL http://localhost:8080/Plone/prefs_install_products_form. @@ -148,10 +123,10 @@ First, configure your project according to the instructions in the tabbed interf Select the tab according to your Python package manager. ```{tip} -For projects created with Cookieplone, select either the tab labeled: +For projects created with Cookieplone, select the tab labeled: -- {guilabel}`uv` if the file {file}`backend/pyproject.toml`, under the table `[tool.uv]` has the setting of `managed = true` -- {guilabel}`pip` if your project doesn't have this setting +- {guilabel}`pip` if your project has the file {file}`backend/mx.ini` +- {guilabel}`uv` if your project doesn't have this file ``` `````{tab-set} @@ -247,6 +222,11 @@ eggs = [sources] collective.easyform = git https://github.com/collective/collective.easyform.git ``` + +```{seealso} +This approach uses the [`mr.developer`](https://pypi.org/project/mr.developer/) Buildout extension. +``` + ```` ````` @@ -260,43 +240,7 @@ This way you always get the version that's currently available in the source con ### Install the add-on -Stop the backend with {kbd}`ctrl-c`. - -To actually download and install the new add-on, run the following command. - -`````{tab-set} -````{tab-item} uv -:sync: uv - -```shell -make backend-build -``` -```` - -````{tab-item} pip -:sync: pip - -```shell -make backend-build -``` -```` - -````{tab-item} Buildout -:sync: buildout - -```shell -bin/buildout -``` -```{seealso} -This approach uses the [`mr.developer`](https://pypi.org/project/mr.developer/) Buildout extension. -``` -```` -````` - -Next, restart the backend. - -```{seealso} -{doc}`run-plone` +```{include} /_inc/_build-and-restart.md ``` In your web browser, and assuming you are currently logged in as an administrator, visit the URL http://localhost:8080/Plone/prefs_install_products_form. diff --git a/docs/admin-guide/override-core.md b/docs/admin-guide/override-core.md index 0d0004cbb..0ee292d26 100644 --- a/docs/admin-guide/override-core.md +++ b/docs/admin-guide/override-core.md @@ -16,16 +16,30 @@ Sometimes you will need to override one or more package versions to fix a bug. ## Override the version of a core Plone package -For instructions of how to override a core Plone package, select the tab below according to your Python package manager. +The Python packages which are dependencies of Plone are pinned to specific versions at the time a Plone release is created. +This section describes how to override the version of one of these packages, in case you need a newer one. + +```{caution} +By doing this, you are intentionally using a combination of package versions that has not been tested by the Plone development team. +Use at your own risk! +``` + +### Configure package installation + +First, configure your project according to the instructions in the tabbed interface below. +Select the tab according to your Python package manager. ```{tip} -Select the tab for uv if you have a project that was created using Cookieplone, and you have `managed = true` set in the `[tool.uv]` section of the file {file}`backend/pyproject.toml`. -Select the tab for pip if you have a project that was created using Cookieplone that does not have this setting. +For projects created with Cookieplone, select the tab labeled: + +- {guilabel}`pip` if your project has the file {file}`backend/mx.ini` +- {guilabel}`uv` if your project doesn't have this file ``` `````{tab-set} ````{tab-item} uv +:sync: uv Edit `constraint-dependencies` in the file {file}`pyproject.toml`. This example uses `plone.api`. @@ -37,25 +51,12 @@ constraint-dependencies = [ ] ``` -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} pip +:sync: pip -Add a version override to the file {file}`mx.ini`. +Add a version override to the file {file}`backend/mx.ini`. This example uses `plone.api`. ``` @@ -66,26 +67,13 @@ version-overrides = ```{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`. - -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` +For an explanation of why Plone uses `mxdev`, see {ref}`manage-packages-mxdev-label`. ``` ```` ````{tab-item} Buildout +:sync: buildout Update the file {file}`buildout.cfg`. This example uses `plone.api`. @@ -113,36 +101,36 @@ plone.api = 2.0.0a3 The version pins specified in the `[versions]` section will take precedence over the pins inherited from `https://dist.plone.org/release/6-latest/versions.cfg`. ``` -To actually download and install the new package version, run the following command. +```` -```shell -bin/buildout -N -``` +````` -Then restart your instance. +### Install the package -```{seealso} -{doc}`run-plone` +```{include} /_inc/_build-and-restart.md ``` -```` - -````` - ## Install a core Plone package from source A core Plone package can be installed from a source control system such as GitHub. +This is useful for developing and testing changes in core Plone packages. + +### Configure package installation -For instructions, select the tab below according to your Python package manager. +First, configure your project according to the instructions in the tabbed interface below. +Select the tab according to your Python package manager. ```{tip} -Select the tab for uv if you have a project that was created using Cookieplone, and you have `managed = true` set in the `[tool.uv]` section of the file {file}`backend/pyproject.toml`. -Select the tab for pip if you have a project that was created using Cookieplone that does not have this setting. +For projects created with Cookieplone, select the tab labeled: + +- {guilabel}`pip` if your project has the file {file}`backend/mx.ini` +- {guilabel}`uv` if your project doesn't have this file ``` `````{tab-set} ````{tab-item} uv +:sync: uv This example uses `plone.restapi`. @@ -159,19 +147,12 @@ 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 +:sync: pip -Add the Plone package you want to check out in the file {file}`mx.ini`. +Add the Plone package you want to check out in the file {file}`backend/mx.ini`. This example uses `plone.restapi`. ```cfg @@ -186,23 +167,10 @@ 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 +:sync: buildout Update the file {file}`buildout.cfg`. This example uses `plone.restapi`. @@ -236,18 +204,6 @@ plone.restapi = Setting an empty version ensures that the copy of `plone.restapi` from source control will be used, instead of the version pin inherited from https://dist.plone.org/release/6-latest/versions.cfg. ``` -To actually download and install the new add-on, run the following command. - -```shell -bin/buildout -``` - -Then restart your instance. - -```{seealso} -{doc}`run-plone` -``` - ```{seealso} This approach uses the [`mr.developer`](https://pypi.org/project/mr.developer/) Buildout extension. ``` @@ -255,3 +211,8 @@ This approach uses the [`mr.developer`](https://pypi.org/project/mr.developer/) ```` ````` + +### Install the package + +```{include} /_inc/_build-and-restart.md +``` From d650a08712ec9f1dd9cc609b9410a24626f48d45 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 27 Mar 2026 15:36:53 -0700 Subject: [PATCH 17/18] Another revision of uv-managed branch (#2074) * More uv managed revisions - The instructions for installation from PyPI have only two options, Cookieplone and Buildout, not the three options from the include. The attempt to avoid DRY with an include won't work here. * - DRY for complete the add-on installation * "mxdev" isn't an inline literal * "mxdev" isn't an inline literal * tighten up spacing * grammar * Increasing specificity * Make URL clickable * Add an introductory paragraph to the empty subheading * - Link to sections in add-ons documentation - spelling of mxdev and pip - Oxford comma * Fix Vale errors * Fix Vale errors * Remove unnecessary section subheading * Promote uv as the first package manager, and combine its first two sentences. * MyST markup, grammar, link to the pip interface for uv * Update docs/conceptual-guides/package-management.md * Update docs/admin-guide/override-core.md Co-authored-by: David Glick --------- Co-authored-by: David Glick --- docs/_inc/_add-on-complete-install.md | 7 +++ docs/admin-guide/add-ons.md | 45 ++++++++++++++------ docs/admin-guide/override-core.md | 24 +++-------- docs/conceptual-guides/package-management.md | 41 +++++++++--------- styles/config/vocabularies/Plone/accept.txt | 8 +++- 5 files changed, 74 insertions(+), 51 deletions(-) create mode 100644 docs/_inc/_add-on-complete-install.md diff --git a/docs/_inc/_add-on-complete-install.md b/docs/_inc/_add-on-complete-install.md new file mode 100644 index 000000000..e9255c5c1 --- /dev/null +++ b/docs/_inc/_add-on-complete-install.md @@ -0,0 +1,7 @@ +In your web browser, and assuming you are currently logged in as an administrator, visit the URL http://localhost:8080/Plone/prefs_install_products_form. + +Then click the {guilabel}`Install` button next to your add-on to complete installation of the add-on. + +Some add-ons have configuration options. +To configure such add-ons, return to the {guilabel}`Site Setup` control panel. +At the bottom of the page, you should see the heading {guilabel}`Add-on Configuration`, and a control panel to configure the add-on that you just installed. diff --git a/docs/admin-guide/add-ons.md b/docs/admin-guide/add-ons.md index 95f46d798..eb6f0a7fb 100644 --- a/docs/admin-guide/add-ons.md +++ b/docs/admin-guide/add-ons.md @@ -98,17 +98,39 @@ You can control which version of an add-on to install through "version pinning." ### Install the add-on -```{include} /_inc/_build-and-restart.md +If the backend is running, stop it with {kbd}`ctrl-c`. + +To actually download and install the new add-on, run the following command. + +`````{tab-set} +````{tab-item} Cookieplone +:sync: cookieplone + +```shell +make backend-build +``` +```` + +````{tab-item} Buildout +:sync: buildout + +```shell +bin/buildout -N ``` +```` +````` + +Next, restart the backend. -In your web browser, and assuming you are currently logged in as an administrator, visit the URL http://localhost:8080/Plone/prefs_install_products_form. +```{seealso} +{doc}`run-plone` +``` -Then click the {guilabel}`Install` button next to your add-on to complete installation of the add-on. +```{include} /_inc/_add-on-complete-install.md +``` -Some add-ons have configuration options. -To configure such add-ons, return to the {guilabel}`Site Setup` control panel. -At the bottom of the page, you should see the heading {guilabel}`Add-on Configuration`, and a control panel to configure the add-on that you just installed. +(install-an-add-on-from-source-label)= ## Install an add-on from source @@ -190,7 +212,7 @@ 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`. +For an explanation of why Plone uses mxdev, see {ref}`manage-packages-mxdev-label`. ``` ```` @@ -243,10 +265,5 @@ This way you always get the version that's currently available in the source con ```{include} /_inc/_build-and-restart.md ``` -In your web browser, and assuming you are currently logged in as an administrator, visit the URL http://localhost:8080/Plone/prefs_install_products_form. - -Then click the {guilabel}`Install` button next to your add-on to complete installation of the add-on. - -Some add-ons have configuration options. -To configure such add-ons, return to the {guilabel}`Site Setup` control panel. -At the bottom of the page, you should see the heading {guilabel}`Add-on Configuration`, and a control panel to configure the add-on that you just installed. +```{include} /_inc/_add-on-complete-install.md +``` diff --git a/docs/admin-guide/override-core.md b/docs/admin-guide/override-core.md index 0ee292d26..f428fa841 100644 --- a/docs/admin-guide/override-core.md +++ b/docs/admin-guide/override-core.md @@ -16,11 +16,11 @@ Sometimes you will need to override one or more package versions to fix a bug. ## Override the version of a core Plone package -The Python packages which are dependencies of Plone are pinned to specific versions at the time a Plone release is created. +Plone's Python package dependencies are pinned to specific versions at the time a Plone release is created. This section describes how to override the version of one of these packages, in case you need a newer one. ```{caution} -By doing this, you are intentionally using a combination of package versions that has not been tested by the Plone development team. +When you override package versions, the combination of packages isn't tested by the Plone development team. Use at your own risk! ``` @@ -37,11 +37,10 @@ For projects created with Cookieplone, select the tab labeled: ``` `````{tab-set} - ````{tab-item} uv :sync: uv -Edit `constraint-dependencies` in the file {file}`pyproject.toml`. +In the file {file}`pyproject.toml`, under the table `[tool.uv]`, edit `constraint-dependencies`. This example uses `plone.api`. ``` @@ -50,13 +49,12 @@ constraint-dependencies = [ "plone.api==2.0.0a3", ] ``` - ```` ````{tab-item} pip :sync: pip -Add a version override to the file {file}`backend/mx.ini`. +In the file {file}`backend/mx.ini`, under the `[settings]` section, add `version-overrides` setting. This example uses `plone.api`. ``` @@ -67,9 +65,8 @@ version-overrides = ```{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`. +For an explanation of why Plone uses mxdev, see {ref}`manage-packages-mxdev-label`. ``` - ```` ````{tab-item} Buildout @@ -98,11 +95,9 @@ plone.api = 2.0.0a3 ``` ```{note} -The version pins specified in the `[versions]` section will take precedence over the pins inherited from `https://dist.plone.org/release/6-latest/versions.cfg`. +The version pins specified in the `[versions]` section will take precedence over the pins inherited from https://dist.plone.org/release/6-latest/versions.cfg. ``` - ```` - ````` ### Install the package @@ -128,7 +123,6 @@ For projects created with Cookieplone, select the tab labeled: ``` `````{tab-set} - ````{tab-item} uv :sync: uv @@ -146,7 +140,6 @@ Add the local directory to your uv project as an editable package. cd backend uv add --editable ../plone.restapi ``` - ```` ````{tab-item} pip @@ -164,9 +157,8 @@ 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`. +For an explanation of why Plone uses mxdev, see {ref}`manage-packages-mxdev-label`. ``` - ```` ````{tab-item} Buildout @@ -207,9 +199,7 @@ Setting an empty version ensures that the copy of `plone.restapi` from source co ```{seealso} This approach uses the [`mr.developer`](https://pypi.org/project/mr.developer/) Buildout extension. ``` - ```` - ````` ### Install the package diff --git a/docs/conceptual-guides/package-management.md b/docs/conceptual-guides/package-management.md index 05970a81b..e488a89f7 100644 --- a/docs/conceptual-guides/package-management.md +++ b/docs/conceptual-guides/package-management.md @@ -11,7 +11,7 @@ myst: Plone 6 consists of a collection of Python and Node.js packages. Over the decades of its existence, Plone has used several package management tools, sometimes multiple tools at one time. -Each one has its strengths and weaknesses for performing specific tasks, such as installation, conflict resolution, updates and upgrades, and working with virtual environments and across platforms. +Each one has its strengths and weaknesses for performing specific tasks, such as installation, conflict resolution, updates, upgrades, and working with virtual environments and across platforms. With Volto as the default frontend in Plone 6, first npm, then pnpm, was brought into the mix as a package manager for its Node.js packages. @@ -26,6 +26,21 @@ Python itself has a complex and convoluted history with package management, as [ ## Manage backend Python packages +uv, pip with mxdev, and buildout are supported tools to manage the Python packages in the Plone backend. +The following sections explain each of these tools in more detail. + + +### uv + +{term}`uv` is a package manager which 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 its {file}`pyproject.toml` file, and its packages are installed using `uv sync`. + +uv also has a [pip interface](https://docs.astral.sh/uv/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. + + ### pip By convention in the Python community, {term}`pip` is commonly used to install Python packages. @@ -49,37 +64,26 @@ As a best practice, pip should always be used inside a specific Python {term}`vi 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 +- {ref}`install a newer version of a core Plone package that was released to PyPI ` with a bugfix +- {ref}`install an unreleased core Plone package from a source control system ` -Unfortunately pip does not allow overriding constraints this way. +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. +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. Then it fetches the requirements and constraints of Plone. Finally, it writes new combined requirements in {file}`requirements-mxdev.txt` and new constraints in {file}`constraints-mxdev.txt`. Together these two files contain the combined requirements and constraints, but modified according to the configuration in {file}`mx.ini`. The generated files indicate from where the constraints were fetched, and comments are added when a modification was necessary. -`mxdev` does not run `pip` or install packages. +mxdev does not run pip or install packages. You or your development tools, such as GNU Make, must perform that step. ```{seealso} {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. @@ -89,9 +93,8 @@ It not only installs packages, but can set up other things using an extensible s 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 -### pnpm +## Manage frontend Node.js packages Plone uses {term}`pnpm` to install Node.js packages. diff --git a/styles/config/vocabularies/Plone/accept.txt b/styles/config/vocabularies/Plone/accept.txt index b3666e096..c0b583ac1 100644 --- a/styles/config/vocabularies/Plone/accept.txt +++ b/styles/config/vocabularies/Plone/accept.txt @@ -10,24 +10,28 @@ backport(ed|ing) Barceloneta [Bb]oolean bugfix -buildout +[Bb]uildout cacheable Classic UI +CMSs CMSUI CommonJS Cookieplone doctest ETags? +extranets [Ff]avicon folderish fieldset getter +interoperate JavaScript [Jj]enkins jQuery libxslt middleware Mockup +mxdev namespaces? npm nvm @@ -39,6 +43,7 @@ PLIP(s) Plone plonecli pluggab(le|ility) +pnpm [Pp]ortlets? prerendered programatically @@ -67,4 +72,5 @@ Volto Vue webpack wireframe +xkcd Zope From 16cd84f7a307cd407dc211eafe5266ef24213940 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 27 Mar 2026 20:14:58 -0700 Subject: [PATCH 18/18] Link to Python standard library --- docs/glossary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/glossary.md b/docs/glossary.md index 2652cb377..1ee4f8e3c 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -982,5 +982,5 @@ virtualenv Since Python 3.3, a subset of it has been integrated into the standard library under the {term}`venv` module. venv - The `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 {file}`site-packages` directories. + The {mod}`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 {file}`site-packages` directories. ```