From 4a4cc22d1b581e539bd6a74413ab3649a4023c91 Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Tue, 8 Oct 2024 11:04:21 +0200 Subject: [PATCH 01/32] Document distributions in the 6.1 upgrade guide. See https://github.com/plone/Products.CMFPlone/issues/3854 --- .../images/zope-root-distributions.png | Bin 0 -> 108786 bytes .../upgrade-to-61.md | 79 ++++++++++++++++++ docs/glossary.md | 8 +- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 docs/backend/upgrading/version-specific-migration/images/zope-root-distributions.png diff --git a/docs/backend/upgrading/version-specific-migration/images/zope-root-distributions.png b/docs/backend/upgrading/version-specific-migration/images/zope-root-distributions.png new file mode 100644 index 0000000000000000000000000000000000000000..afe6172273fda55b6a8824c1c592a98e2895664c GIT binary patch literal 108786 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

Q*F9lDMU17p*^wx{WijAecGUM(gjgh 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 literal 0 HcmV?d00001 diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index 47655a1aa..3c387a9a8 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -117,3 +117,82 @@ If you have an existing Plone 5.2 or 6.0 site and you migrate to 6.1, then migra - If the `plone.app.discussion` Python package is _not_ in your setup, but the site has existing comments (discussions), then the migration code stops with an error. Apparently you _were_ using comments in your site. Add the `plone.app.discussion` package to your dependencies, and run the migration again. + + +## Distributions + +Plone 6.1 introduces the concept of a Plone {term}`distribution`. +The idea for distributions has been around for a long time. +Now it is available in core Plone as the recommended way for creating a Plone site. +A Plone distribution defines its Python package dependencies and add-ons that are always activated when creating a new site. +It defines content items, plus possibly extras like users. + +When you install the `Plone` 6.1 Python package you get several new packages and two distributions: + +* `plone.distribution` is the main new package that offers the basis for distributions. +* `plone.exportimport` is the way for importing and exporting content, users, etc. + `plone.distribution` uses this. +* `plone.volto` is the default distribution. + This package was already there in Plone 6.0, but has gotten an upgrade to a distribution. + This would be the distribution that you use for creating a Plone site for use with the default Volto frontend. +* `plone.classicui` is a new package and contains the Classic UI distribution. + This would be the distribution that you use for creating a Plone site with the server side Classic UI frontend. + +When you start a new project with `Plone` 6.1 the Zope root looks like this when there are no Plone sites yet: + +```{image} images/zope-root-distributions.png +``` + +On the left you can create a Plone site with the default distribution (`plone.volto`) and on the right with the Classic UI distribution. +Clicking will show more or less the same form with questions as you would get before in Plone 6.0. + +If you don't want to use distributions, you don't have to. +If your project only uses the `Products.CMFPlone` Python package, you can still create a Plone site in the usual way. +The form is simpler and shorted though. +The created site has no content, so no News or Events folders. +You can't select extra add-ons to install. +You can still activate extra add-ons in the Add-ons control panel. + +There are a few things you should consider when upgrading a project to 6.1 or making an add-on compatible: + +* In general, you don't need no change anything. + Your existing site will keep working. + But adding a new site may change in the ways described earlier. +* Do you want to use the `Products.CMFPlone` package (0 distributions), `plone.volto/classicui` (1 distribution) or `Plone` (2 distributions)? +* When your site used the default Volto frontend, you will already have `plone.volto` as dependency. + This can stay the same. +* When your site is only using the `Products.CMFPlone` package, this is a Classic UI site. + This can stay the same, but you may want to depend on `plone.classicui`. + With that package you can still create a new site and have the same content as before. +* When your site is using the `Plone` package, you will have the two new distributions available. + This is fine. + If you know you only need `plone.volto` or only need `plone.classicui`, you can switch to that. + You can also limit the options for selecting a distribution by setting the environment variable `ALLOWED_DISTRIBUTIONS` with fewer options. + Set `ALLOWED_DISTRIBUTIONS=default` for the default distribution (`plone.volto`). + Set `ALLOWED_DISTRIBUTIONS=classic` for the classic distribution (`plone.classicui`). +* If you switch from `Plone` to `plone.volto` or `plone.classicui` you may want to install extra core add-ons, for example `plone.app.upgrade` or `plone.app.caching`. +* If your add-on is only for Volto, you may want to add `plone.volto` as dependency. +* If your add-on is only for Classic UI, you may want to add `plone.classicui` as dependency. + Note though that `plone.classicui` is not available for Plone 6.0. + +You can create your own distributions. +Some use cases for this: + +* Create a distribution demonstrating your favorite setup for Plone. + This would contain the add-ons that you usually add in each project, including example content. + With this you can create a fully configured Plone site filled with content for a potential client. + Or they can try it themselves if the distribution is available publicly. +* Create a distribution for an internal or client project. + This would create a site with all add-ons activated and configured for this project, including example content and maybe users. + During the development phase of a new project all developers would use this to create a fresh site locally so that everyone has the same setup and contents. + Before the project goes live, you can use the distribution to create the initial setup. + +Note: in Plone 7 the aim is to create a clearer separation between Classic UI and the core `Products.CMFPlone` backend. +This means in Plone 7 `Products.CMFPlone` will have less code and pull in less dependencies. +`plone.classicui` may have more code and pull in more dependencies. +This is the direction the backend is heading in, and the introduction of the `plone.classicui` distribution package is an important step for this. + +For detailed information, see the source code of the new packages: + +* [`plone.distribution`](https://github.com/plone/plone.distribution/) +* [`plone.exportimport`](https://github.com/plone/plone.exportimport/) diff --git a/docs/glossary.md b/docs/glossary.md index d637dca9b..59a9db3e0 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -777,7 +777,7 @@ Load balancer CI continuous integration Continuous integration (CI) is the practice of integrating all your code changes into the main branch of a shared source code repository early and often, automatically testing each change when you commit or merge them, and automatically kicking off a build. - + Read about Plone's {doc}`/contributing/core/continuous-integration`. CD @@ -794,4 +794,10 @@ lazy loaded reference implementation A reference implementation is a program that implements all requirements from a corresponding specification. The reference implementation often accompanies a technical standard, and demonstrates what should be considered the "correct" behavior of any other implementation of it. + +distribution + A Plone distribution is a Python package that defines a distribution of Plone. + It is a way of defining what happens when you create a new Plone site. + A distribution defines dependencies and default content, including default users. + This is new in Plone 6.1. ``` From 7a20cee9f9ec9f034e64aec0d7aa7eb4fedc17c9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 8 Oct 2024 21:10:28 -0700 Subject: [PATCH 02/32] Review of Distributions documentation --- ...ributions.png => distribution-chooser.png} | Bin .../upgrade-to-61.md | 122 +++++++++--------- 2 files changed, 60 insertions(+), 62 deletions(-) rename docs/backend/upgrading/version-specific-migration/images/{zope-root-distributions.png => distribution-chooser.png} (100%) diff --git a/docs/backend/upgrading/version-specific-migration/images/zope-root-distributions.png b/docs/backend/upgrading/version-specific-migration/images/distribution-chooser.png similarity index 100% rename from docs/backend/upgrading/version-specific-migration/images/zope-root-distributions.png rename to docs/backend/upgrading/version-specific-migration/images/distribution-chooser.png diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index 3c387a9a8..5430e0585 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -122,77 +122,75 @@ If you have an existing Plone 5.2 or 6.0 site and you migrate to 6.1, then migra ## Distributions Plone 6.1 introduces the concept of a Plone {term}`distribution`. -The idea for distributions has been around for a long time. +A Plone distribution is a Python package that defines specific features, themes, add-ons, and configurations that get activated when creating a Plone site. Now it is available in core Plone as the recommended way for creating a Plone site. -A Plone distribution defines its Python package dependencies and add-ons that are always activated when creating a new site. -It defines content items, plus possibly extras like users. -When you install the `Plone` 6.1 Python package you get several new packages and two distributions: +When you install the [`Plone` 6.1 Python package](https://pypi.org/project/Plone/), you get several new packages and two distributions: -* `plone.distribution` is the main new package that offers the basis for distributions. -* `plone.exportimport` is the way for importing and exporting content, users, etc. - `plone.distribution` uses this. -* `plone.volto` is the default distribution. - This package was already there in Plone 6.0, but has gotten an upgrade to a distribution. - This would be the distribution that you use for creating a Plone site for use with the default Volto frontend. -* `plone.classicui` is a new package and contains the Classic UI distribution. - This would be the distribution that you use for creating a Plone site with the server side Classic UI frontend. +- [`plone.distribution`](https://github.com/plone/plone.distribution) is the new main package that offers the basis for distributions. +- [`plone.exportimport`](https://github.com/plone/plone.exportimport) imports and exports content, users, and other objects between Plone sites and when upgrading Plone. + It is now the preferred method, and `plone.distribution` uses it. +- [`plone.volto`](https://github.com/plone/plone.volto) is the distribution to create a Plone site with the default frontend Volto. + This package was already present in Plone 6.0, but was upgraded to a distribution. +- [`plone.classicui`](https://github.com/plone/plone.classicui) is a new package and is the distribution to create a Plone site with the Classic UI frontend. -When you start a new project with `Plone` 6.1 the Zope root looks like this when there are no Plone sites yet: +When you start a new project with `Plone` 6.1, the launch screen prompts you to choose a frontend distribution when creating a new Plone site. -```{image} images/zope-root-distributions.png +```{image} images/distribution-chooser.png +:alt: screenshot of the launch screen ``` -On the left you can create a Plone site with the default distribution (`plone.volto`) and on the right with the Classic UI distribution. -Clicking will show more or less the same form with questions as you would get before in Plone 6.0. +After you select a frontend distribution, you will fill out a brief form to configure your new Plone 6.1 site, similar to the process for Plone 6.0. -If you don't want to use distributions, you don't have to. +Distributions are optional. If your project only uses the `Products.CMFPlone` Python package, you can still create a Plone site in the usual way. -The form is simpler and shorted though. -The created site has no content, so no News or Events folders. -You can't select extra add-ons to install. -You can still activate extra add-ons in the Add-ons control panel. - -There are a few things you should consider when upgrading a project to 6.1 or making an add-on compatible: - -* In general, you don't need no change anything. - Your existing site will keep working. - But adding a new site may change in the ways described earlier. -* Do you want to use the `Products.CMFPlone` package (0 distributions), `plone.volto/classicui` (1 distribution) or `Plone` (2 distributions)? -* When your site used the default Volto frontend, you will already have `plone.volto` as dependency. - This can stay the same. -* When your site is only using the `Products.CMFPlone` package, this is a Classic UI site. - This can stay the same, but you may want to depend on `plone.classicui`. - With that package you can still create a new site and have the same content as before. -* When your site is using the `Plone` package, you will have the two new distributions available. - This is fine. - If you know you only need `plone.volto` or only need `plone.classicui`, you can switch to that. - You can also limit the options for selecting a distribution by setting the environment variable `ALLOWED_DISTRIBUTIONS` with fewer options. - Set `ALLOWED_DISTRIBUTIONS=default` for the default distribution (`plone.volto`). - Set `ALLOWED_DISTRIBUTIONS=classic` for the classic distribution (`plone.classicui`). -* If you switch from `Plone` to `plone.volto` or `plone.classicui` you may want to install extra core add-ons, for example `plone.app.upgrade` or `plone.app.caching`. -* If your add-on is only for Volto, you may want to add `plone.volto` as dependency. -* If your add-on is only for Classic UI, you may want to add `plone.classicui` as dependency. - Note though that `plone.classicui` is not available for Plone 6.0. - -You can create your own distributions. -Some use cases for this: - -* Create a distribution demonstrating your favorite setup for Plone. - This would contain the add-ons that you usually add in each project, including example content. - With this you can create a fully configured Plone site filled with content for a potential client. - Or they can try it themselves if the distribution is available publicly. -* Create a distribution for an internal or client project. - This would create a site with all add-ons activated and configured for this project, including example content and maybe users. - During the development phase of a new project all developers would use this to create a fresh site locally so that everyone has the same setup and contents. - Before the project goes live, you can use the distribution to create the initial setup. - -Note: in Plone 7 the aim is to create a clearer separation between Classic UI and the core `Products.CMFPlone` backend. -This means in Plone 7 `Products.CMFPlone` will have less code and pull in less dependencies. +Consider, however, the following differences from distributions. + +- The configuration form is simpler and shorter. +- The created site has no content, and therefore no {guilabel}`News` or {guilabel}`Events` folders. +- You must install then activate add-ons through the {guilabel}`Add-ons` control panel. + +There are a few things you should consider when upgrading a project to, or making an add-on compatible with, Plone 6.1: + +- In general, you don't need no change anything. + Your existing site will keep working. + But adding a new site may change in the ways described earlier. +- Do you want to use the `Products.CMFPlone` package (0 distributions), either `plone.volto` or `plone.classicui` (1 distribution), or `Plone` (2 distributions)? +- When your site used the default Volto frontend, you will already have `plone.volto` as a dependency. + This can stay the same. +- When your site uses only the `Products.CMFPlone` package, the frontend is Classic UI. + This can stay the same, but you may want to depend on `plone.classicui`. + With that package you can still create a new site and have the same content as before. +- When your site is using the `Plone` package, you will have the two new distributions available. + This is fine. + If you know you only need `plone.volto` or only need `plone.classicui`, you can switch to that. + You can also limit the options for selecting a distribution by setting the environment variable `ALLOWED_DISTRIBUTIONS` with fewer options. + Set `ALLOWED_DISTRIBUTIONS=default` for the default Volto frontend distribution (`plone.volto`). + Set `ALLOWED_DISTRIBUTIONS=classic` for the Classic UI frontend distribution (`plone.classicui`). +- If you switch from `Plone` to `plone.volto` or `plone.classicui`, you might want to install extra core add-ons, for example `plone.app.upgrade` or `plone.app.caching`. +- If your add-on is only for Volto, you may want to add `plone.volto` as a dependency. +- If your add-on is only for Classic UI, you may want to add `plone.classicui` as a dependency. + Note though that `plone.classicui` is not available for Plone 6.0. + +You can create your own distributions to suit your needs. + +- Create a distribution demonstrating your favorite setup for Plone. + This would contain the add-ons that you usually add in each project, including example content. + With this you can create a fully configured Plone site filled with content for a potential client. + Or they can try it themselves if the distribution is available publicly. +- Create a distribution for an internal or client project. + This would create a site with all add-ons activated and configured for this project, including example content, and optionally users and groups. + During the development phase of a new project, all developers would use this to create a fresh site locally so that everyone has the same configuration and content. + Before the project goes live, you can use the distribution to create the initial setup. + +```{note} +For Plone 7, the [Plone roadmap](https://plone.org/why-plone/roadmap) guides development toward a clearer separation between the Classic UI frontend and the core `Products.CMFPlone` backend. +This means in Plone 7 `Products.CMFPlone` will have less code and pull in fewer dependencies. `plone.classicui` may have more code and pull in more dependencies. -This is the direction the backend is heading in, and the introduction of the `plone.classicui` distribution package is an important step for this. +This is the direction in which the backend is heading, and the introduction of the `plone.classicui` distribution package is an important step along this path. +``` -For detailed information, see the source code of the new packages: +For detailed information, see the source code of the new packages. -* [`plone.distribution`](https://github.com/plone/plone.distribution/) -* [`plone.exportimport`](https://github.com/plone/plone.exportimport/) +- [`plone.distribution`](https://github.com/plone/plone.distribution/) +- [`plone.exportimport`](https://github.com/plone/plone.exportimport/) From 1bc1a9b83bf4ac537229c3a2eab81a8b0803cbf6 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 8 Oct 2024 21:13:45 -0700 Subject: [PATCH 03/32] Align term definition with upgrade guide docs, avoiding circular reference. --- docs/glossary.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/glossary.md b/docs/glossary.md index 59a9db3e0..ee4a57d61 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -796,8 +796,8 @@ reference implementation The reference implementation often accompanies a technical standard, and demonstrates what should be considered the "correct" behavior of any other implementation of it. distribution - A Plone distribution is a Python package that defines a distribution of Plone. - It is a way of defining what happens when you create a new Plone site. - A distribution defines dependencies and default content, including default users. - This is new in Plone 6.1. + ```{versionadded} Plone 6.1``` + + A Plone distribution is a Python package that defines specific features, themes, add-ons, and configurations that get activated when creating a Plone site. + It is available in core Plone as the recommended way for creating a Plone site. ``` From d370c782f1aaab87da6ffdf9336428f4c58c1e9e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 8 Oct 2024 21:23:21 -0700 Subject: [PATCH 04/32] Fix admonition syntax --- docs/glossary.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/glossary.md b/docs/glossary.md index ee4a57d61..d752c9fde 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -796,7 +796,9 @@ reference implementation The reference implementation often accompanies a technical standard, and demonstrates what should be considered the "correct" behavior of any other implementation of it. distribution - ```{versionadded} Plone 6.1``` + + ```{versionadded} Plone 6.1 + ``` A Plone distribution is a Python package that defines specific features, themes, add-ons, and configurations that get activated when creating a Plone site. It is available in core Plone as the recommended way for creating a Plone site. From bb99d925f8385fa3962afae061f4fe9388c904f7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 8 Oct 2024 21:24:12 -0700 Subject: [PATCH 05/32] Add link to repo --- docs/glossary.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/glossary.md b/docs/glossary.md index d752c9fde..b6ce22809 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -802,4 +802,5 @@ distribution A Plone distribution is a Python package that defines specific features, themes, add-ons, and configurations that get activated when creating a Plone site. It is available in core Plone as the recommended way for creating a Plone site. + [`plone.distribution`](https://github.com/plone/plone.distribution) is the main package that offers the basis for distributions. ``` From 7331a00271aa9314b6aceeecf00106b3b3423b4d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 8 Oct 2024 21:31:23 -0700 Subject: [PATCH 06/32] Enhance screenshot with card syntax --- .../version-specific-migration/upgrade-to-61.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index 5430e0585..9c81665ca 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -136,9 +136,14 @@ When you install the [`Plone` 6.1 Python package](https://pypi.org/project/Plone When you start a new project with `Plone` 6.1, the launch screen prompts you to choose a frontend distribution when creating a new Plone site. -```{image} images/distribution-chooser.png -:alt: screenshot of the launch screen +````{card} +```{image} /backend/upgrading/version-specific-migration/images/distribution-chooser.png +:alt: Launch screen for choosing a frontend distribution +:target: /_images/distribution-chooser.png ``` ++++ +_Launch screen for choosing a frontend distribution_ +```` After you select a frontend distribution, you will fill out a brief form to configure your new Plone 6.1 site, similar to the process for Plone 6.0. From a1059ca8c73a214c0ebbddcdf6a605bb991942e5 Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Wed, 9 Oct 2024 08:53:59 +0200 Subject: [PATCH 07/32] plone.exportimport is not for upgrading Plone. If you need an export/import for upgrading Plone you would still use collective.exportimport. Upgrading is not a use case that plone.exportimport covers. --- .../upgrading/version-specific-migration/upgrade-to-61.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index 9c81665ca..5ea504434 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -128,8 +128,8 @@ Now it is available in core Plone as the recommended way for creating a Plone si When you install the [`Plone` 6.1 Python package](https://pypi.org/project/Plone/), you get several new packages and two distributions: - [`plone.distribution`](https://github.com/plone/plone.distribution) is the new main package that offers the basis for distributions. -- [`plone.exportimport`](https://github.com/plone/plone.exportimport) imports and exports content, users, and other objects between Plone sites and when upgrading Plone. - It is now the preferred method, and `plone.distribution` uses it. +- [`plone.exportimport`](https://github.com/plone/plone.exportimport) imports and exports content, users, and other objects between Plone sites. + `plone.distribution` uses it. - [`plone.volto`](https://github.com/plone/plone.volto) is the distribution to create a Plone site with the default frontend Volto. This package was already present in Plone 6.0, but was upgraded to a distribution. - [`plone.classicui`](https://github.com/plone/plone.classicui) is a new package and is the distribution to create a Plone site with the Classic UI frontend. From 486def16f3fdc77a8ab5f0003a336e7c05ce35a0 Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Wed, 9 Oct 2024 09:06:11 +0200 Subject: [PATCH 08/32] Here we do not start a new project, I just mean: start Plone. --- .../upgrading/version-specific-migration/upgrade-to-61.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index 5ea504434..07754d28b 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -134,7 +134,7 @@ When you install the [`Plone` 6.1 Python package](https://pypi.org/project/Plone This package was already present in Plone 6.0, but was upgraded to a distribution. - [`plone.classicui`](https://github.com/plone/plone.classicui) is a new package and is the distribution to create a Plone site with the Classic UI frontend. -When you start a new project with `Plone` 6.1, the launch screen prompts you to choose a frontend distribution when creating a new Plone site. +When you start Plone, the launch screen prompts you to choose a distribution when creating a new Plone site. ````{card} ```{image} /backend/upgrading/version-specific-migration/images/distribution-chooser.png From 47da6fd616a2dc4c9ba85c701ca6e03a0d492294 Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Wed, 9 Oct 2024 09:15:03 +0200 Subject: [PATCH 09/32] These are not 'frontend distributions'. --- .../version-specific-migration/upgrade-to-61.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index 07754d28b..16759d8cc 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -138,14 +138,14 @@ When you start Plone, the launch screen prompts you to choose a distribution whe ````{card} ```{image} /backend/upgrading/version-specific-migration/images/distribution-chooser.png -:alt: Launch screen for choosing a frontend distribution +:alt: Launch screen for choosing a distribution :target: /_images/distribution-chooser.png ``` +++ -_Launch screen for choosing a frontend distribution_ +_Launch screen for choosing a distribution_ ```` -After you select a frontend distribution, you will fill out a brief form to configure your new Plone 6.1 site, similar to the process for Plone 6.0. +After you select a distribution, you will fill out a brief form to configure your new Plone 6.1 site, similar to the process for Plone 6.0. Distributions are optional. If your project only uses the `Products.CMFPlone` Python package, you can still create a Plone site in the usual way. @@ -170,8 +170,8 @@ There are a few things you should consider when upgrading a project to, or makin This is fine. If you know you only need `plone.volto` or only need `plone.classicui`, you can switch to that. You can also limit the options for selecting a distribution by setting the environment variable `ALLOWED_DISTRIBUTIONS` with fewer options. - Set `ALLOWED_DISTRIBUTIONS=default` for the default Volto frontend distribution (`plone.volto`). - Set `ALLOWED_DISTRIBUTIONS=classic` for the Classic UI frontend distribution (`plone.classicui`). + Set `ALLOWED_DISTRIBUTIONS=default` for the distribution targeting the default Volto frontend (`plone.volto`). + Set `ALLOWED_DISTRIBUTIONS=classic` for the distribution with the Classic UI frontend (`plone.classicui`). - If you switch from `Plone` to `plone.volto` or `plone.classicui`, you might want to install extra core add-ons, for example `plone.app.upgrade` or `plone.app.caching`. - If your add-on is only for Volto, you may want to add `plone.volto` as a dependency. - If your add-on is only for Classic UI, you may want to add `plone.classicui` as a dependency. From 8c6e57f3eb184e5218ad7881754e3e4fc85a33a2 Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Wed, 9 Oct 2024 09:30:41 +0200 Subject: [PATCH 10/32] Creating a 6.1 CMFPlone site differs from 6.0, that is the main point here. --- .../upgrading/version-specific-migration/upgrade-to-61.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index 16759d8cc..814ad2a0c 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -149,11 +149,11 @@ After you select a distribution, you will fill out a brief form to configure you Distributions are optional. If your project only uses the `Products.CMFPlone` Python package, you can still create a Plone site in the usual way. -Consider, however, the following differences from distributions. +Consider, however, the following differences from distributions and from Plone 6.0. - The configuration form is simpler and shorter. - The created site has no content, and therefore no {guilabel}`News` or {guilabel}`Events` folders. -- You must install then activate add-ons through the {guilabel}`Add-ons` control panel. +- You must install and then activate add-ons through the {guilabel}`Add-ons` control panel. There are a few things you should consider when upgrading a project to, or making an add-on compatible with, Plone 6.1: From 73facb0654492aa9ff012a1dd1a0056d5b8e44fa Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Wed, 9 Oct 2024 09:43:35 +0200 Subject: [PATCH 11/32] Don't mention installing add-ons here, activating is enough. Sure, the Python package of an add-on must be installed before you can activate it, but the same is true for a distribution. The plone.classicui distribution has basically the same Python package dependencies as CMFPlone, although it activates a few extra ones automatically if they are available (say plone.app.caching). --- .../upgrading/version-specific-migration/upgrade-to-61.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index 814ad2a0c..e8dcda1d1 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -153,7 +153,7 @@ Consider, however, the following differences from distributions and from Plone 6 - The configuration form is simpler and shorter. - The created site has no content, and therefore no {guilabel}`News` or {guilabel}`Events` folders. -- You must install and then activate add-ons through the {guilabel}`Add-ons` control panel. +- You must activate add-ons through the {guilabel}`Add-ons` control panel. There are a few things you should consider when upgrading a project to, or making an add-on compatible with, Plone 6.1: From 8052b2a5792985fed33055908c4d57d7bb6b20ad Mon Sep 17 00:00:00 2001 From: David Glick Date: Thu, 31 Oct 2024 12:40:14 -0700 Subject: [PATCH 12/32] reorganize distribution docs --- .../upgrade-to-61.md | 63 +--- docs/conceptual-guides/distributions.md | 79 +++++ docs/conceptual-guides/index.md | 1 + docs/developer-guide/create-a-distribution.md | 294 ++++++++++++++++++ docs/glossary.md | 10 +- docs/install/add-site.md | 75 +++++ docs/install/index.md | 1 + 7 files changed, 464 insertions(+), 59 deletions(-) create mode 100644 docs/conceptual-guides/distributions.md create mode 100644 docs/developer-guide/create-a-distribution.md create mode 100644 docs/install/add-site.md diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index e8dcda1d1..9137e8fb5 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -123,32 +123,14 @@ If you have an existing Plone 5.2 or 6.0 site and you migrate to 6.1, then migra Plone 6.1 introduces the concept of a Plone {term}`distribution`. A Plone distribution is a Python package that defines specific features, themes, add-ons, and configurations that get activated when creating a Plone site. -Now it is available in core Plone as the recommended way for creating a Plone site. +Now it is available in core Plone as the recommended way for {doc}`creating a new Plone site `. -When you install the [`Plone` 6.1 Python package](https://pypi.org/project/Plone/), you get several new packages and two distributions: - -- [`plone.distribution`](https://github.com/plone/plone.distribution) is the new main package that offers the basis for distributions. -- [`plone.exportimport`](https://github.com/plone/plone.exportimport) imports and exports content, users, and other objects between Plone sites. - `plone.distribution` uses it. -- [`plone.volto`](https://github.com/plone/plone.volto) is the distribution to create a Plone site with the default frontend Volto. - This package was already present in Plone 6.0, but was upgraded to a distribution. -- [`plone.classicui`](https://github.com/plone/plone.classicui) is a new package and is the distribution to create a Plone site with the Classic UI frontend. - -When you start Plone, the launch screen prompts you to choose a distribution when creating a new Plone site. - -````{card} -```{image} /backend/upgrading/version-specific-migration/images/distribution-chooser.png -:alt: Launch screen for choosing a distribution -:target: /_images/distribution-chooser.png +```{seealso} +For more information, see {doc}`/conceptual-guides/distributions`. ``` -+++ -_Launch screen for choosing a distribution_ -```` - -After you select a distribution, you will fill out a brief form to configure your new Plone 6.1 site, similar to the process for Plone 6.0. Distributions are optional. -If your project only uses the `Products.CMFPlone` Python package, you can still create a Plone site in the usual way. +If your project only uses the `Products.CMFPlone` Python package, you can still create a Plone site in the old way. Consider, however, the following differences from distributions and from Plone 6.0. - The configuration form is simpler and shorter. @@ -157,45 +139,22 @@ Consider, however, the following differences from distributions and from Plone 6 There are a few things you should consider when upgrading a project to, or making an add-on compatible with, Plone 6.1: -- In general, you don't need no change anything. +- In general, you don't need to change anything. Your existing site will keep working. But adding a new site may change in the ways described earlier. - Do you want to use the `Products.CMFPlone` package (0 distributions), either `plone.volto` or `plone.classicui` (1 distribution), or `Plone` (2 distributions)? -- When your site used the default Volto frontend, you will already have `plone.volto` as a dependency. +- If your site uses the default Volto frontend, you will already have `plone.volto` as a dependency. This can stay the same. -- When your site uses only the `Products.CMFPlone` package, the frontend is Classic UI. +- If your site uses only the `Products.CMFPlone` package, the frontend is Classic UI. This can stay the same, but you may want to depend on `plone.classicui`. With that package you can still create a new site and have the same content as before. -- When your site is using the `Plone` package, you will have the two new distributions available. +- If your site uses the `Plone` package, you will have the two new distributions available. This is fine. - If you know you only need `plone.volto` or only need `plone.classicui`, you can switch to that. + If you know you only need `plone.volto` or only need `plone.classicui`, you can switch to only that one. You can also limit the options for selecting a distribution by setting the environment variable `ALLOWED_DISTRIBUTIONS` with fewer options. Set `ALLOWED_DISTRIBUTIONS=default` for the distribution targeting the default Volto frontend (`plone.volto`). Set `ALLOWED_DISTRIBUTIONS=classic` for the distribution with the Classic UI frontend (`plone.classicui`). - If you switch from `Plone` to `plone.volto` or `plone.classicui`, you might want to install extra core add-ons, for example `plone.app.upgrade` or `plone.app.caching`. -- If your add-on is only for Volto, you may want to add `plone.volto` as a dependency. -- If your add-on is only for Classic UI, you may want to add `plone.classicui` as a dependency. +- If your add-on is only for Volto, you might want to add `plone.volto` as a dependency. +- If your add-on is only for Classic UI, you might want to add `plone.classicui` as a dependency. Note though that `plone.classicui` is not available for Plone 6.0. - -You can create your own distributions to suit your needs. - -- Create a distribution demonstrating your favorite setup for Plone. - This would contain the add-ons that you usually add in each project, including example content. - With this you can create a fully configured Plone site filled with content for a potential client. - Or they can try it themselves if the distribution is available publicly. -- Create a distribution for an internal or client project. - This would create a site with all add-ons activated and configured for this project, including example content, and optionally users and groups. - During the development phase of a new project, all developers would use this to create a fresh site locally so that everyone has the same configuration and content. - Before the project goes live, you can use the distribution to create the initial setup. - -```{note} -For Plone 7, the [Plone roadmap](https://plone.org/why-plone/roadmap) guides development toward a clearer separation between the Classic UI frontend and the core `Products.CMFPlone` backend. -This means in Plone 7 `Products.CMFPlone` will have less code and pull in fewer dependencies. -`plone.classicui` may have more code and pull in more dependencies. -This is the direction in which the backend is heading, and the introduction of the `plone.classicui` distribution package is an important step along this path. -``` - -For detailed information, see the source code of the new packages. - -- [`plone.distribution`](https://github.com/plone/plone.distribution/) -- [`plone.exportimport`](https://github.com/plone/plone.exportimport/) diff --git a/docs/conceptual-guides/distributions.md b/docs/conceptual-guides/distributions.md new file mode 100644 index 000000000..65db58b12 --- /dev/null +++ b/docs/conceptual-guides/distributions.md @@ -0,0 +1,79 @@ +--- +myst: + html_meta: + "description": "A Plone distribution is a pre-packaged version of Plone that includes specific features, themes, modules, and configurations." + "property=og:description": "A Plone distribution is a pre-packaged version of Plone that includes specific features, themes, modules, and configurations." + "property=og:title": "Plone distributions" + "keywords": "Plone 6, distribution, plone.distribution" +--- + +(plone-distributions-label)= + +# Plone distributions + +```{versionadded} Plone 6.1 +``` + +A Plone distribution is a pre-packaged version of Plone that includes specific features, themes, modules, and configurations. +It is a convenient way to get a specific type of website up and running quickly, as the distribution includes everything needed to run that type of site. + + +## Similar Concept in Other CMS + +- **Drupal:** Drupal has distributions for blogs, e-commerce sites, and intranet portals. + +- **WordPress:** WordPress has a similar concept in the form of "WordPress Multisite," which allows users to run multiple websites from a single installation of WordPress. + +- **Joomla:** Joomla has a similar concept in the form of "Joomla Templates," which are pre-designed templates for Joomla websites. + +- **TYPO3:** TYPO3 has a similar concept in the form of "TYPO3 Distributions," which are pre-configured installations of TYPO3 for specific types of websites. + + +## Built-in distributions + +Plone comes with two built-in distributions, which correspond to the two Plone user interfaces: +- `default` (Volto) +- `classic` (Classic UI) + + +## Third-party distributions + +You can create your own distributions to suit your needs. + +```{seealso} +For a how-to guide, see {doc}`/developer-guide/create-a-distribution`. +``` + +For example, a Plone consulting agency can create a distribution demonstrating its favorite setup for Plone. +This would contain the add-ons that they usually add in each project, including example content. +With this, the agency can create a fully configured Plone site filled with content for a potential client. + +Or, an agency or implementer can create a distribution for specific project. +This would create a site with all add-ons activated and configured for this project, including example content, and optionally users and groups. +During the development phase of a new project, all developers would use this to create a fresh site locally so that everyone has the same configuration and content. + +Custom Plone distributions can be distributions for use by others. +Examples of third-party Plone distributions include: + +- [SENAITE](https://www.senaite.com) +- [Quaive](https://quaivecloud.com/) +- [Portal Modelo](https://www.interlegis.leg.br/produtos-servicos/portal-modelo/) +- [Portal Padrão](https://identidade-digital-de-governo-plone.readthedocs.io/en/latest/) + + +## Related packages + +The implementation of distributions in the Plone codebase is found in the following Python packages: + +- [`plone.distribution`](https://github.com/plone/plone.distribution) provides the framework for defining distributions. +- [`plone.exportimport`](https://github.com/plone/plone.exportimport) imports and exports content, users, and other objects between Plone sites. + `plone.distribution` uses it. +- [`plone.volto`](https://github.com/plone/plone.volto) is the distribution to create a Plone site with the default frontend, Volto. +- [`plone.classicui`](https://github.com/plone/plone.classicui) is the distribution to create a Plone site with the Classic UI frontend. + +```{note} +For Plone 7, the [Plone roadmap](https://plone.org/why-plone/roadmap) guides development toward a clearer separation between the Classic UI frontend and the core `Products.CMFPlone` backend. +This means that in Plone 7, `Products.CMFPlone` will have less code and pull in fewer dependencies. +`plone.classicui` may have more code and pull in more dependencies. +This is the direction in which the backend is heading, and the introduction of the `plone.classicui` distribution package is an important step along this path. +``` diff --git a/docs/conceptual-guides/index.md b/docs/conceptual-guides/index.md index 727810e41..505888d69 100644 --- a/docs/conceptual-guides/index.md +++ b/docs/conceptual-guides/index.md @@ -15,6 +15,7 @@ This part of the documentation provides explanation of concepts to deepen and br ```{toctree} :maxdepth: 2 +distributions package-management make-build-backend-walk-through ``` diff --git a/docs/developer-guide/create-a-distribution.md b/docs/developer-guide/create-a-distribution.md new file mode 100644 index 000000000..e1d14b6b8 --- /dev/null +++ b/docs/developer-guide/create-a-distribution.md @@ -0,0 +1,294 @@ +--- +myst: + html_meta: + "description": "How to create a custom Plone distribution" + "property=og:description": "How to create a custom Plone distribution" + "property=og:title": "Create a Plone distribution" + "keywords": "Plone 6, distribution, plone.distribution" +--- + +(create-a-plone-distribution-label)= + +# Create a Plone distribution + +A Plone distribution is a pre-packaged version of Plone that includes specific features, themes, modules, and configurations. +This section explains how a developer can create a custom Plone distribution. + +```{seealso} +For a conceptual guide, see {doc}`/conceptual-guides/distributions`. +``` + +## Create a backend add-on + +These instructions assume that you already have created a Plone backend add-on package, +and now you want to add a distribution to it. + +A Plone distribution exists inside a Python Package that can be installed by `pip`. + +## Update `setup.py` + +The package will follow some conventions to make it "discoverable" by others. + +In `setup.py`, always add the correct Trove classifiers: + +```python + "Framework :: Plone", + "Framework :: Plone :: 6.0", + "Framework :: Plone :: Distribution", +``` + +and also require `plone.distribution` to be available: + +```python + install_requires=[ + "Plone", + "setuptools", + "plone.distribution", + ], +``` + +## Update `configure.zcml` + +In your main `configure.zcml`, make sure to have the `plone` XML namespace declared: + +```xml + +``` + +And also include `plone.distribution`: + +```xml + +``` + +Then declare the distributions included in your package: + +```xml + +``` + +This example registers a distribution that will configure a Personal Blog, with some default content. + +## Add distribution handlers + +When registering a distribution, you can provide a `pre_handler`, a `handler` and a `post_handler` which must be +functions with the following signatures. + +```python +def pre_handler(answers: dict) -> dict: + return answers + +def handler(distribution: Distribution, site, answers: dict): + return site + +def post_handler(distribution: Distribution, site, answers: dict): + return site +``` + +Each of those handlers will be called in this way: + +- `pre_handler`: it will process the answers to do modifications on them before creating the site +- `handler`: it will be run after the bare Plone site will be created, but instead of the default handler that installs the required GenericSetup profiles and creates the content. +- `post_handler`: it will be run after the site is set up. + +If you have added some extra fields in the Plone site creation form and want to do some extra configuration in the +Plone site, you can add your own handler and register as follows: + +```xml + +``` + +## Add a distribution folder + +A convention is to use the `distributions/`folder in the root of your package to organize your distribution configuration. + +In that folder, you will need to provide: + +### `image.png` + +A 1080x768 image of your distribution. It could be the default page of a new site, your logo, or any other way of representing this distribution. + +### `profiles.json` + +A `JSON` file with the GenericSetup profiles that are used by your distribution during installation. + +This file needs to contain two keys: + +- **base**: List of profiles installed in every new site using this distribution. + +- **content**: List of profiles installed when the user decides to create a site with example content. + +The configuration for a new Volto site is: + +```json +{ + "base": [ + "plone.app.contenttypes:default", + "plone.app.caching:default", + "plonetheme.barceloneta:default", + "plone.volto:default" + ], + "content": [ + "plone.volto:default-homepage" + ] +} +``` + +### `schema.json` + +In case you require additional input from the user during site creation, you can customize the form using the `schema.json` file. + +The file should contain two keys: + +- **schema**: A JSON Schema definition. +- **uischema**: A [react-jsonschema-form](https://rjsf-team.github.io/react-jsonschema-form/docs/) configuration to modify how the form is displayed. + +The **schema** should have at least the following keys: + +- site_id +- title +- description +- default_language +- portal_timezone +- setup_content + +The `schema.json` used for the default site creation is: + +```json +{ + "schema": { + "title": "Create a Plone site", + "description": "Adds a new Plone content management system site to the underlying application server.", + "type": "object", + "required": [ + "site_id", + "title" + ], + "properties": { + "site_id": { + "type": "string", + "title": "Path Identifier", + "default": "Plone", + "description": "The ID of the site. No special characters or spaces are allowed. This ends up as part of the URL unless hidden by an upstream web server." + }, + "title": { + "type": "string", + "title": "Title", + "default": "Site", + "description": "A short title for the site. This will be shown as part of the title of the browser window on each page." + }, + "description": { + "type": "string", + "title": "Site Description", + "default": "A Plone Site" + }, + "default_language": {"$ref": "#/definitions/languages"}, + "portal_timezone": {"$ref": "#/definitions/timezones"}, + "setup_content": { + "type": "boolean", + "title": "Create Content", + "description": "Should example content be added during site creation?", + "default": false + } + } + }, + "uischema": { + } +} +``` + +:::{note} +You probably noticed the entries for `default_language`: + +```json +{"$ref": "#/definitions/languages"} +``` + +and `portal_timezone`: + +```json +{"$ref": "#/definitions/timezones"} +``` + +Both definitions are added in runtime by `plone.distribution` to provide a list of languages and timezones available on the installation. +::: + +## Add a dependency on an add-on + +If you want to add a Plone backend add-on to your Plone distribution, then you must perform the following steps. + +Add your add-on, such as `collective.person`, to your `setup.py`: + +```python + install_requires=[ + "setuptools", + "Plone", + "plone.distribution>=1.0.0b2", + "plone.api", + "collective.person", + ], +``` + +Add it to your `dependencies.zcml`: + +```xml + + + + + + + +``` + +Add it to your `profiles.json`: + +```json + "base": [ + "plone.app.contenttypes:default", + "plone.app.caching:default", + "plone.restapi:default", + "plone.volto:default", + "collective.person:default", + "plonetheme.barceloneta:default" + ], +``` + +## Add example content + +The distribution's content is loaded from JSON data in the `content` folder. + +To export content from a site into this folder, use the `bin/export-distribution` script. + +```shell +bin/export-distribution path/to/zope.conf Plone +``` + +In the example above, "Plone" is the ID of the Plone site to export. + +## Limit available distributions + +By default, Plone 6.1 ships with two ready-to-use distributions: + +- **default**: Plone Site (Volto frontend) +- **classic**: Plone Site (Classic UI) + +If you want to limit the choice of distributions when creating a new site, it is possible to set the environment variable `ALLOWED_DISTRIBUTIONS` with fewer options: + +```shell +ALLOWED_DISTRIBUTIONS=default +``` diff --git a/docs/glossary.md b/docs/glossary.md index b6ce22809..3c21bf18c 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -796,11 +796,7 @@ reference implementation The reference implementation often accompanies a technical standard, and demonstrates what should be considered the "correct" behavior of any other implementation of it. distribution - - ```{versionadded} Plone 6.1 - ``` - - A Plone distribution is a Python package that defines specific features, themes, add-ons, and configurations that get activated when creating a Plone site. - It is available in core Plone as the recommended way for creating a Plone site. - [`plone.distribution`](https://github.com/plone/plone.distribution) is the main package that offers the basis for distributions. + A Plone distribution is a pre-packaged version of Plone that includes specific features, themes, modules, and configurations. + It is a convenient way to get a specific type of website up and running quickly, as the distribution includes everything needed to run that type of site. + See {doc}`/conceptual-guides/distributions` for more information. ``` diff --git a/docs/install/add-site.md b/docs/install/add-site.md new file mode 100644 index 000000000..e5bacf36a --- /dev/null +++ b/docs/install/add-site.md @@ -0,0 +1,75 @@ +--- +myst: + html_meta: + "description": "How to add a Plone site to an existing Zope instance" + "property=og:description": "How to add a Plone site to an existing Zope instance" + "property=og:title": "Create a Plone site" + "keywords": "Plone 6, create, add, factory, distributions" +--- + +% This should move into the Admin guide once https://github.com/plone/documentation/pull/1746 is merged. + +(add-a-plone-site-label)= + +# Add a Plone site + +This section explains how to add a Plone site to an existing Zope instance. +It assumes that you have already {doc}`installed ` and started Plone. + +Some installation methods create a Plone site for you already. +Follow these instructions if you used an installation method that did not do this, +or if you need a second Plone site in the same instance for some reason. + +```{versionadded} Plone 6.1 +The user interface for creating a new Plone site was changed in Plone 6.1. +You can access it the same way in Plone 6.0, but the appearance and options are different. +``` + +Open the Plone backend. Usually it is running at http://localhost:8080/ + +This launch screen prompts you to choose one of the available {term}`distributions ` to create a new site. + +% add a link to choose-user-interface doc once https://github.com/plone/documentation/pull/1749 is merged + +````{card} +```{image} /backend/upgrading/version-specific-migration/images/distribution-chooser.png +:alt: Launch screen for choosing a distribution +:target: /_images/distribution-chooser.png +``` ++++ +_Launch screen for choosing a distribution_ +```` + +Hover over your choice and click the {guilabel}`Create` button. + +Now complete the form with initial configuration for your site. You can configure: + +:::{card} +Path Identifier +: The ID of the site. This ends up as part of the URL unless hidden by an upstream web server. + +Title +: The name of the site in the HTML `title` element. This will be shown as part of the title of the browser tab on each page. + +Site Description +: A brief description that will be served in an HTML `meta` tag. + +Site Logo +: Upload an image as the main site logo. + +Language +: The main language of the site. + +Timezone +: The default timezone setting of the portal. +::: + +Finally, press {guilabel}`Submit`. + +Have fun with your new Plone site! + +```{important} +If you are using the Volto frontend, keep in mind that the launch screen for adding a site is hosted by the Plone backend server. +After you create the site, you must switch to Volto. +Usually, it is running at http://localhost:3000. +``` diff --git a/docs/install/index.md b/docs/install/index.md index 1f8c95ce7..32d796106 100644 --- a/docs/install/index.md +++ b/docs/install/index.md @@ -56,4 +56,5 @@ create-project create-project-classic-ui create-project-cookieplone containers/index +add-site ``` From ac367b749922d1072e3775da55d7a3cdd98e0731 Mon Sep 17 00:00:00 2001 From: David Glick Date: Thu, 31 Oct 2024 19:48:41 -0700 Subject: [PATCH 13/32] Apply suggestions from code review --- docs/developer-guide/create-a-distribution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/developer-guide/create-a-distribution.md b/docs/developer-guide/create-a-distribution.md index e1d14b6b8..f720c7016 100644 --- a/docs/developer-guide/create-a-distribution.md +++ b/docs/developer-guide/create-a-distribution.md @@ -33,7 +33,7 @@ In `setup.py`, always add the correct Trove classifiers: ```python "Framework :: Plone", - "Framework :: Plone :: 6.0", + "Framework :: Plone :: 6.1", "Framework :: Plone :: Distribution", ``` @@ -41,7 +41,7 @@ and also require `plone.distribution` to be available: ```python install_requires=[ - "Plone", + "Products.CMFPlone", "setuptools", "plone.distribution", ], From e25b72dcb9c3b1cd5fdf07f4730a2c74fba301bf Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 3 Nov 2024 17:57:21 -0800 Subject: [PATCH 14/32] Update conceptual guide for distributions, where the significant changes are: - Use the actual package names of the built-in distributions - Move the comparison to other CMSs to the end of the page, putting Plone-only content first. --- docs/conceptual-guides/distributions.md | 44 ++++++++++++++----------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/docs/conceptual-guides/distributions.md b/docs/conceptual-guides/distributions.md index 65db58b12..d255cc537 100644 --- a/docs/conceptual-guides/distributions.md +++ b/docs/conceptual-guides/distributions.md @@ -18,22 +18,15 @@ A Plone distribution is a pre-packaged version of Plone that includes specific f It is a convenient way to get a specific type of website up and running quickly, as the distribution includes everything needed to run that type of site. -## Similar Concept in Other CMS - -- **Drupal:** Drupal has distributions for blogs, e-commerce sites, and intranet portals. - -- **WordPress:** WordPress has a similar concept in the form of "WordPress Multisite," which allows users to run multiple websites from a single installation of WordPress. - -- **Joomla:** Joomla has a similar concept in the form of "Joomla Templates," which are pre-designed templates for Joomla websites. - -- **TYPO3:** TYPO3 has a similar concept in the form of "TYPO3 Distributions," which are pre-configured installations of TYPO3 for specific types of websites. +## Built-in distributions +Plone comes with two built-in distributions, which correspond to the two Plone user interfaces. -## Built-in distributions +[`plone.volto`](https://github.com/plone/plone.volto) +: Create a Plone site with the Volto frontend. -Plone comes with two built-in distributions, which correspond to the two Plone user interfaces: -- `default` (Volto) -- `classic` (Classic UI) +[`plone.classicui`](https://github.com/plone/plone.classicui) +: Create a Plone site with the Classic UI frontend. ## Third-party distributions @@ -48,8 +41,8 @@ For example, a Plone consulting agency can create a distribution demonstrating i This would contain the add-ons that they usually add in each project, including example content. With this, the agency can create a fully configured Plone site filled with content for a potential client. -Or, an agency or implementer can create a distribution for specific project. -This would create a site with all add-ons activated and configured for this project, including example content, and optionally users and groups. +Alternatively, an agency or implementer can create a distribution for specific project. +This could create a site with all add-ons activated and configured for this project, including example content, and optionally users and groups. During the development phase of a new project, all developers would use this to create a fresh site locally so that everyone has the same configuration and content. Custom Plone distributions can be distributions for use by others. @@ -63,17 +56,30 @@ Examples of third-party Plone distributions include: ## Related packages -The implementation of distributions in the Plone codebase is found in the following Python packages: +The implementation of distributions in the Plone codebase is found in the following Python packages. - [`plone.distribution`](https://github.com/plone/plone.distribution) provides the framework for defining distributions. - [`plone.exportimport`](https://github.com/plone/plone.exportimport) imports and exports content, users, and other objects between Plone sites. `plone.distribution` uses it. -- [`plone.volto`](https://github.com/plone/plone.volto) is the distribution to create a Plone site with the default frontend, Volto. +- [`plone.volto`](https://github.com/plone/plone.volto) is the distribution to create a Plone site with the Volto frontend. - [`plone.classicui`](https://github.com/plone/plone.classicui) is the distribution to create a Plone site with the Classic UI frontend. ```{note} For Plone 7, the [Plone roadmap](https://plone.org/why-plone/roadmap) guides development toward a clearer separation between the Classic UI frontend and the core `Products.CMFPlone` backend. -This means that in Plone 7, `Products.CMFPlone` will have less code and pull in fewer dependencies. -`plone.classicui` may have more code and pull in more dependencies. +This means that in Plone 7, `Products.CMFPlone` will have less code and pull in fewer dependencies, whereas `plone.classicui` may have more code and pull in more dependencies. This is the direction in which the backend is heading, and the introduction of the `plone.classicui` distribution package is an important step along this path. ``` + +## Comparison with other CMSs + +Drupal +: Drupal has distributions for blogs, e-commerce sites, and intranet portals. + +WordPress +: WordPress has a similar concept in the form of "WordPress Multisite," which allows users to run multiple websites from a single installation of WordPress. + +Joomla +: Joomla has a similar concept in the form of "Joomla Templates," which are pre-designed templates for Joomla websites. + +TYPO3 +: TYPO3 has a similar concept in the form of "TYPO3 Distributions," which are pre-configured installations of TYPO3 for specific types of websites. From d36830f93ff478d9ef7830c866ceaa27d50282df Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 3 Nov 2024 18:12:03 -0800 Subject: [PATCH 15/32] Create an entry in `index.md` to include a new `developer-guide/index.md` and the new `developer-guide/create-a-distribution.md` --- docs/developer-guide/index.md | 19 +++++++++++++++++++ docs/index.md | 1 + 2 files changed, 20 insertions(+) create mode 100644 docs/developer-guide/index.md diff --git a/docs/developer-guide/index.md b/docs/developer-guide/index.md new file mode 100644 index 000000000..867f46c58 --- /dev/null +++ b/docs/developer-guide/index.md @@ -0,0 +1,19 @@ +--- +myst: + html_meta: + "description": "Plone developer guide" + "property=og:description": "Plone developer guide" + "property=og:title": "Developer guide" + "keywords": "Plone 6, developer guide, development" +--- + +# Developer guide + +This part of the documentation provides information for how to develop in Plone. + + +```{toctree} +:maxdepth: 2 + +create-a-distribution +``` diff --git a/docs/index.md b/docs/index.md index 40d53f511..a64831021 100644 --- a/docs/index.md +++ b/docs/index.md @@ -33,6 +33,7 @@ Read the [documentation for the previous version, Plone 5](https://5.docs.plone. overview/index install/index manage/index +developer-guide/index upgrade/index deployment/index volto/index From a7ead92666d72af163da5c4dc53836628bd19d70 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 3 Nov 2024 18:13:44 -0800 Subject: [PATCH 16/32] Update glossary reference to other distribution material --- docs/glossary.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/glossary.md b/docs/glossary.md index e74cc8d5e..d89af17e8 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -804,5 +804,9 @@ reference implementation distribution A Plone distribution is a pre-packaged version of Plone that includes specific features, themes, modules, and configurations. It is a convenient way to get a specific type of website up and running quickly, as the distribution includes everything needed to run that type of site. - See {doc}`/conceptual-guides/distributions` for more information. + + ```{seealso} + - {doc}`/conceptual-guides/distributions` + - {doc}`/developer-guide/create-a-distribution` + ``` ``` From 007a75569c8f99d8145d89830227a77304b1bc7e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 3 Nov 2024 18:17:15 -0800 Subject: [PATCH 17/32] Add cross-reference --- docs/conceptual-guides/distributions.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/conceptual-guides/distributions.md b/docs/conceptual-guides/distributions.md index d255cc537..80ff4a4bb 100644 --- a/docs/conceptual-guides/distributions.md +++ b/docs/conceptual-guides/distributions.md @@ -14,9 +14,13 @@ myst: ```{versionadded} Plone 6.1 ``` -A Plone distribution is a pre-packaged version of Plone that includes specific features, themes, modules, and configurations. +A Plone {term}`distribution` is a pre-packaged version of Plone that includes specific features, themes, modules, and configurations. It is a convenient way to get a specific type of website up and running quickly, as the distribution includes everything needed to run that type of site. +```{seealso} +To create your own distribution, see {doc}`/developer-guide/create-a-distribution`. +``` + ## Built-in distributions From 5c0f1972a563ae5ddc46e1331a36044f1478e635 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 3 Nov 2024 22:19:16 -0800 Subject: [PATCH 18/32] Add JSON Schema to Glossary --- docs/glossary.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/glossary.md b/docs/glossary.md index d89af17e8..5d070f130 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -809,4 +809,8 @@ distribution - {doc}`/conceptual-guides/distributions` - {doc}`/developer-guide/create-a-distribution` ``` + +JSON Schema + [JSON Schema](https://json-schema.org/) is the vocabulary that enables JSON data consistency, validity, and interoperability at scale. + ``` From 5c458919962222ee48df44f2c32ec0d5540fbdfb Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 3 Nov 2024 22:23:27 -0800 Subject: [PATCH 19/32] Tidy up create-a-distribution.md. - Rewrite passive voice to active. - Enhance code blocks with `emphasize-lines`. - Use definition lists as appropriate for terms and inline literals. - Add links and terms where helpful. --- docs/developer-guide/create-a-distribution.md | 229 ++++++++++-------- 1 file changed, 129 insertions(+), 100 deletions(-) diff --git a/docs/developer-guide/create-a-distribution.md b/docs/developer-guide/create-a-distribution.md index f720c7016..6b57eb26e 100644 --- a/docs/developer-guide/create-a-distribution.md +++ b/docs/developer-guide/create-a-distribution.md @@ -11,76 +11,83 @@ myst: # Create a Plone distribution +This section explains how a developer can create a custom Plone {term}`distribution`. A Plone distribution is a pre-packaged version of Plone that includes specific features, themes, modules, and configurations. -This section explains how a developer can create a custom Plone distribution. ```{seealso} For a conceptual guide, see {doc}`/conceptual-guides/distributions`. ``` + ## Create a backend add-on These instructions assume that you already have created a Plone backend add-on package, and now you want to add a distribution to it. -A Plone distribution exists inside a Python Package that can be installed by `pip`. +A Plone distribution exists inside a Python package that can be installed by `pip`. + ## Update `setup.py` -The package will follow some conventions to make it "discoverable" by others. +Your package should follow conventions that make it discoverable by other developers. -In `setup.py`, always add the correct Trove classifiers: +In your {file}`setup.py` file, always add the correct [Python Trove classifiers](https://pypi.org/classifiers/). ```python - "Framework :: Plone", - "Framework :: Plone :: 6.1", - "Framework :: Plone :: Distribution", +"Framework :: Plone", +"Framework :: Plone :: 6.1", +"Framework :: Plone :: Distribution", ``` -and also require `plone.distribution` to be available: +Add `plone.distribution` to your `install_requires` stanza in your {file}`setup.py` file. -```python - install_requires=[ - "Products.CMFPlone", - "setuptools", - "plone.distribution", - ], +```{code-block} python +:emphasize-lines: 4 + +install_requires=[ + "Products.CMFPlone", + "setuptools", + "plone.distribution", +], ``` + ## Update `configure.zcml` -In your main `configure.zcml`, make sure to have the `plone` XML namespace declared: +In your main {file}`configure.zcml` file, add the `plone` XML namespace with the following declaration. + +```{code-block} xml +:emphasize-lines: 3 -```xml ``` -And also include `plone.distribution`: +Register `plone.distribution` as a package to include with the following `` directive. ```xml ``` -Then declare the distributions included in your package: +Then declare the distributions you want to include in your package. ```xml - + ``` -This example registers a distribution that will configure a Personal Blog, with some default content. +The above example registers a distribution that will configure a personal blog with some default content. + ## Add distribution handlers -When registering a distribution, you can provide a `pre_handler`, a `handler` and a `post_handler` which must be -functions with the following signatures. +When registering a distribution, you can provide a `pre_handler`, a `handler`, and a `post_handler`, each of which must be a function with their respective signature, as shown in the following example. ```python def pre_handler(answers: dict) -> dict: @@ -93,46 +100,58 @@ def post_handler(distribution: Distribution, site, answers: dict): return site ``` -Each of those handlers will be called in this way: +Each of those handlers will be called as follows. -- `pre_handler`: it will process the answers to do modifications on them before creating the site -- `handler`: it will be run after the bare Plone site will be created, but instead of the default handler that installs the required GenericSetup profiles and creates the content. -- `post_handler`: it will be run after the site is set up. +`pre_handler` +: Processes the answers to prepare the distribution before creating the site. -If you have added some extra fields in the Plone site creation form and want to do some extra configuration in the -Plone site, you can add your own handler and register as follows: +`handler` +: Runs after creating the bare Plone site instead of the default handler. + It installs the required GenericSetup profiles and creates the content. -```xml - +`post_handler` +: Runs after the site is set up. + +To add extra configuration to your Plone site, and assuming you added extra inputs to the Plone site creation form, then you can add your own handler, registering it as shown in the following example. + +```{code-block} xml +:emphasize-lines: 6 + + ``` -## Add a distribution folder -A convention is to use the `distributions/`folder in the root of your package to organize your distribution configuration. +## Add a distribution folder + +To organize your distribution configuration, you can follow the convention to use the {file}`distributions/` folder in the root of your package. +In that folder, you need to provide the items described in the following sections. -In that folder, you will need to provide: ### `image.png` -A 1080x768 image of your distribution. It could be the default page of a new site, your logo, or any other way of representing this distribution. +A 1080 pixels wide by 768 pixels tall image in PNG format representing your distribution. +It could be the default page of a new site, your logo, or any other way of representing your distribution. + ### `profiles.json` -A `JSON` file with the GenericSetup profiles that are used by your distribution during installation. +A file {file}`profiles.json` containing the GenericSetup profiles that your distribution uses during installation. -This file needs to contain two keys: +This file needs to contain two keys. -- **base**: List of profiles installed in every new site using this distribution. +`base` +: List of profiles to install in every new site using this distribution. -- **content**: List of profiles installed when the user decides to create a site with example content. +`content` +: List of profiles to install when the user decides to create a site with example content. -The configuration for a new Volto site is: +As an example, the configuration for a new Plone site with Volto as its frontend would be the following. ```json { @@ -148,25 +167,29 @@ The configuration for a new Volto site is: } ``` + ### `schema.json` -In case you require additional input from the user during site creation, you can customize the form using the `schema.json` file. +If you require additional input from the user during site creation, you can customize the form using the {file}`schema.json` file. -The file should contain two keys: +The file should contain two keys. -- **schema**: A JSON Schema definition. -- **uischema**: A [react-jsonschema-form](https://rjsf-team.github.io/react-jsonschema-form/docs/) configuration to modify how the form is displayed. +`schema` +: A {term}`JSON Schema` definition. -The **schema** should have at least the following keys: +`uischema` +: A [`react-jsonschema-form`](https://rjsf-team.github.io/react-jsonschema-form/docs/) configuration to modify the display of the form. -- site_id -- title -- description -- default_language -- portal_timezone -- setup_content +The `schema` should have at least the following keys. -The `schema.json` used for the default site creation is: +- `site_id` +- `title` +- `description` +- `default_language` +- `portal_timezone` +- `setup_content` + +The following code example is the content of the {file}`schema.json` file for creating the site. ```json { @@ -211,42 +234,41 @@ The `schema.json` used for the default site creation is: } ``` -:::{note} -You probably noticed the entries for `default_language`: - -```json -{"$ref": "#/definitions/languages"} -``` - -and `portal_timezone`: +````{note} +You may have noticed the entries for both `default_language` and `portal_timezone`. ```json -{"$ref": "#/definitions/timezones"} + "default_language": {"$ref": "#/definitions/languages"}, + "portal_timezone": {"$ref": "#/definitions/timezones"}, ``` -Both definitions are added in runtime by `plone.distribution` to provide a list of languages and timezones available on the installation. -::: +`plone.distribution` adds both definitions at runtime, providing a list of languages and timezones available on the installation. +```` ## Add a dependency on an add-on If you want to add a Plone backend add-on to your Plone distribution, then you must perform the following steps. -Add your add-on, such as `collective.person`, to your `setup.py`: +Add your add-on, such as `collective.person`, to your {file}`setup.py` file's `install_requires` stanza. -```python - install_requires=[ - "setuptools", - "Plone", - "plone.distribution>=1.0.0b2", - "plone.api", - "collective.person", - ], +```{code-block} python +:emphasize-lines: 6 + +install_requires=[ + "setuptools", + "Plone", + "plone.distribution>=1.0.0b2", + "plone.api", + "collective.person", +], ``` -Add it to your `dependencies.zcml`: +Then add it to your {file}`dependencies.zcml` file. -```xml - +```{code-block} xml +:emphasize-lines: 5 + + @@ -255,22 +277,25 @@ Add it to your `dependencies.zcml`: ``` -Add it to your `profiles.json`: +Finally, add it to your {file}`profiles.json` file. -```json - "base": [ - "plone.app.contenttypes:default", - "plone.app.caching:default", - "plone.restapi:default", - "plone.volto:default", - "collective.person:default", - "plonetheme.barceloneta:default" - ], +```{code-block} json +:emphasize-lines: 6 + +"base": [ + "plone.app.contenttypes:default", + "plone.app.caching:default", + "plone.restapi:default", + "plone.volto:default", + "collective.person:default", + "plonetheme.barceloneta:default" +], ``` + ## Add example content -The distribution's content is loaded from JSON data in the `content` folder. +The distribution loads its content from JSON data in the `content` folder. To export content from a site into this folder, use the `bin/export-distribution` script. @@ -278,16 +303,20 @@ To export content from a site into this folder, use the `bin/export-distribution bin/export-distribution path/to/zope.conf Plone ``` -In the example above, "Plone" is the ID of the Plone site to export. +In the example above, `Plone` is the ID of the Plone site to export. + ## Limit available distributions By default, Plone 6.1 ships with two ready-to-use distributions: -- **default**: Plone Site (Volto frontend) -- **classic**: Plone Site (Classic UI) +[`plone.volto`](https://github.com/plone/plone.volto) +: Create a Plone site with the Volto frontend. + +[`plone.classicui`](https://github.com/plone/plone.classicui) +: Create a Plone site with the Classic UI frontend. -If you want to limit the choice of distributions when creating a new site, it is possible to set the environment variable `ALLOWED_DISTRIBUTIONS` with fewer options: +If you want to limit the choice of distributions when creating a new site, it is possible to set the environment variable `ALLOWED_DISTRIBUTIONS` with fewer options. ```shell ALLOWED_DISTRIBUTIONS=default From 28d42eccfe40e4e95a397025dba86a30a5dcf1b8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 3 Nov 2024 23:48:45 -0800 Subject: [PATCH 20/32] Revert distribution names and enhance `ALLOWED_DISTRIBUTIONS` usage. --- docs/developer-guide/create-a-distribution.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/developer-guide/create-a-distribution.md b/docs/developer-guide/create-a-distribution.md index 6b57eb26e..d58e4f3bd 100644 --- a/docs/developer-guide/create-a-distribution.md +++ b/docs/developer-guide/create-a-distribution.md @@ -308,15 +308,15 @@ In the example above, `Plone` is the ID of the Plone site to export. ## Limit available distributions -By default, Plone 6.1 ships with two ready-to-use distributions: +By default, Plone 6.1 ships with two ready-to-use distributions. -[`plone.volto`](https://github.com/plone/plone.volto) +`default` : Create a Plone site with the Volto frontend. -[`plone.classicui`](https://github.com/plone/plone.classicui) +`classic` : Create a Plone site with the Classic UI frontend. -If you want to limit the choice of distributions when creating a new site, it is possible to set the environment variable `ALLOWED_DISTRIBUTIONS` with fewer options. +If you want to limit the choice of distributions when creating a new site, you can set the environment variable `ALLOWED_DISTRIBUTIONS` to a comma-separated sting of only those distributions' names. ```shell ALLOWED_DISTRIBUTIONS=default From ba0e0744cd0e1f14c504f97dea0d746da6143821 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 4 Nov 2024 00:11:09 -0800 Subject: [PATCH 21/32] Tidy up add-site.md, mostly docs style guide stuff, and a rewording of the final admonition. Add plural `distributions` to Glossary. --- docs/glossary.md | 1 + docs/install/add-site.md | 33 +++++++++++++++++---------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/glossary.md b/docs/glossary.md index 5d070f130..2fd60ba99 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -802,6 +802,7 @@ reference implementation The reference implementation often accompanies a technical standard, and demonstrates what should be considered the "correct" behavior of any other implementation of it. distribution +distributions A Plone distribution is a pre-packaged version of Plone that includes specific features, themes, modules, and configurations. It is a convenient way to get a specific type of website up and running quickly, as the distribution includes everything needed to run that type of site. diff --git a/docs/install/add-site.md b/docs/install/add-site.md index e5bacf36a..73d40805c 100644 --- a/docs/install/add-site.md +++ b/docs/install/add-site.md @@ -3,11 +3,11 @@ myst: html_meta: "description": "How to add a Plone site to an existing Zope instance" "property=og:description": "How to add a Plone site to an existing Zope instance" - "property=og:title": "Create a Plone site" + "property=og:title": "Add a Plone site" "keywords": "Plone 6, create, add, factory, distributions" --- -% This should move into the Admin guide once https://github.com/plone/documentation/pull/1746 is merged. +% TODO: This should move into the Admin guide once https://github.com/plone/documentation/pull/1746 is merged. (add-a-plone-site-label)= @@ -17,19 +17,19 @@ This section explains how to add a Plone site to an existing Zope instance. It assumes that you have already {doc}`installed ` and started Plone. Some installation methods create a Plone site for you already. -Follow these instructions if you used an installation method that did not do this, -or if you need a second Plone site in the same instance for some reason. +Follow these instructions if you used an installation method that did not do this, or if you need a second Plone site in the same instance for some reason. ```{versionadded} Plone 6.1 The user interface for creating a new Plone site was changed in Plone 6.1. You can access it the same way in Plone 6.0, but the appearance and options are different. ``` -Open the Plone backend. Usually it is running at http://localhost:8080/ +Visit the Plone backend in a web browser. +Usually it is running at http://localhost:8080/ -This launch screen prompts you to choose one of the available {term}`distributions ` to create a new site. +The launch screen prompts you to choose one of the available {term}`distributions` to create a new site. -% add a link to choose-user-interface doc once https://github.com/plone/documentation/pull/1749 is merged +% TODO: Add a link to the choose-user-interface doc once https://github.com/plone/documentation/pull/1749 is merged. ````{card} ```{image} /backend/upgrading/version-specific-migration/images/distribution-chooser.png @@ -42,14 +42,16 @@ _Launch screen for choosing a distribution_ Hover over your choice and click the {guilabel}`Create` button. -Now complete the form with initial configuration for your site. You can configure: +Now complete the form with initial configuration for your site. +You can configure the following settings. -:::{card} Path Identifier -: The ID of the site. This ends up as part of the URL unless hidden by an upstream web server. +: The ID of the site. + This ends up as part of the URL unless hidden by an upstream web server. Title -: The name of the site in the HTML `title` element. This will be shown as part of the title of the browser tab on each page. +: The name of the site in the HTML `title` element. + This will be shown as part of the title of the browser tab on each page. Site Description : A brief description that will be served in an HTML `meta` tag. @@ -62,14 +64,13 @@ Language Timezone : The default timezone setting of the portal. -::: -Finally, press {guilabel}`Submit`. +Finally, click the {guilabel}`Submit` button. Have fun with your new Plone site! ```{important} -If you are using the Volto frontend, keep in mind that the launch screen for adding a site is hosted by the Plone backend server. -After you create the site, you must switch to Volto. -Usually, it is running at http://localhost:3000. +The launch screen for adding a site is hosted by the Plone backend server. +Regardless of the frontend you select, you will be redirected to the backend's user interface after you create the site. +If you select the Volto frontend, you can switch to it by changing the port number in the URL, usually `3000`, and visiting it at http://localhost:3000, for example. ``` From 7f7890194778704c5889fe1fbd5027489a0d177b Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 4 Nov 2024 00:33:51 -0800 Subject: [PATCH 22/32] Tidy up distributions section in upgrade-to-61.md --- .../version-specific-migration/upgrade-to-61.md | 14 +++++++------- docs/install/add-site.md | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index 9137e8fb5..c6f29b861 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -126,33 +126,33 @@ A Plone distribution is a Python package that defines specific features, themes, Now it is available in core Plone as the recommended way for {doc}`creating a new Plone site `. ```{seealso} -For more information, see {doc}`/conceptual-guides/distributions`. +For more information about distribution concepts, see {doc}`/conceptual-guides/distributions`. ``` Distributions are optional. If your project only uses the `Products.CMFPlone` Python package, you can still create a Plone site in the old way. -Consider, however, the following differences from distributions and from Plone 6.0. +Consider, however, that doing so you will have the following differences when compared to using distributions. - The configuration form is simpler and shorter. - The created site has no content, and therefore no {guilabel}`News` or {guilabel}`Events` folders. - You must activate add-ons through the {guilabel}`Add-ons` control panel. -There are a few things you should consider when upgrading a project to, or making an add-on compatible with, Plone 6.1: +There are a few things you should consider when upgrading a project to, or making an add-on compatible with, Plone 6.1. - In general, you don't need to change anything. Your existing site will keep working. But adding a new site may change in the ways described earlier. -- Do you want to use the `Products.CMFPlone` package (0 distributions), either `plone.volto` or `plone.classicui` (1 distribution), or `Plone` (2 distributions)? -- If your site uses the default Volto frontend, you will already have `plone.volto` as a dependency. +- Do you want to use the `Products.CMFPlone` package (no distributions), either `plone.volto` or `plone.classicui` (one distribution), or `Plone` (two distributions)? +- If your site uses Volto for the frontend, you will already have `plone.volto` as a dependency. This can stay the same. - If your site uses only the `Products.CMFPlone` package, the frontend is Classic UI. This can stay the same, but you may want to depend on `plone.classicui`. With that package you can still create a new site and have the same content as before. - If your site uses the `Plone` package, you will have the two new distributions available. This is fine. - If you know you only need `plone.volto` or only need `plone.classicui`, you can switch to only that one. + If you know you only need `plone.volto` or only need `plone.classicui`, you can switch to only one or the other. You can also limit the options for selecting a distribution by setting the environment variable `ALLOWED_DISTRIBUTIONS` with fewer options. - Set `ALLOWED_DISTRIBUTIONS=default` for the distribution targeting the default Volto frontend (`plone.volto`). + Set `ALLOWED_DISTRIBUTIONS=default` for the distribution targeting the Volto frontend (`plone.volto`). Set `ALLOWED_DISTRIBUTIONS=classic` for the distribution with the Classic UI frontend (`plone.classicui`). - If you switch from `Plone` to `plone.volto` or `plone.classicui`, you might want to install extra core add-ons, for example `plone.app.upgrade` or `plone.app.caching`. - If your add-on is only for Volto, you might want to add `plone.volto` as a dependency. diff --git a/docs/install/add-site.md b/docs/install/add-site.md index 73d40805c..29abafc8a 100644 --- a/docs/install/add-site.md +++ b/docs/install/add-site.md @@ -25,7 +25,7 @@ You can access it the same way in Plone 6.0, but the appearance and options are ``` Visit the Plone backend in a web browser. -Usually it is running at http://localhost:8080/ +Usually it is running at http://localhost:8080/. The launch screen prompts you to choose one of the available {term}`distributions` to create a new site. From 11d6d6c0607f3d3ec6f5520e5f7edd24c70ff8d2 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 4 Nov 2024 20:41:23 -0800 Subject: [PATCH 23/32] Update docs/backend/upgrading/version-specific-migration/upgrade-to-61.md Co-authored-by: David Glick --- .../upgrading/version-specific-migration/upgrade-to-61.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index c6f29b861..d353d2ed1 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -145,7 +145,7 @@ There are a few things you should consider when upgrading a project to, or makin - Do you want to use the `Products.CMFPlone` package (no distributions), either `plone.volto` or `plone.classicui` (one distribution), or `Plone` (two distributions)? - If your site uses Volto for the frontend, you will already have `plone.volto` as a dependency. This can stay the same. -- If your site uses only the `Products.CMFPlone` package, the frontend is Classic UI. +- If your site depends on the `Products.CMFPlone` package without the `Plone` or `plone.volto` packages, then the frontend is Classic UI. This can stay the same, but you may want to depend on `plone.classicui`. With that package you can still create a new site and have the same content as before. - If your site uses the `Plone` package, you will have the two new distributions available. From 606af43a47bc9afbfba59478db331e3d668928f8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 4 Nov 2024 20:58:42 -0800 Subject: [PATCH 24/32] Move add-site into Admin Guide. Move Admin Guide before Developer Guide in main navigation --- docs/{install => admin-guide}/add-site.md | 0 docs/admin-guide/index.md | 1 + docs/index.md | 2 +- 3 files changed, 2 insertions(+), 1 deletion(-) rename docs/{install => admin-guide}/add-site.md (100%) diff --git a/docs/install/add-site.md b/docs/admin-guide/add-site.md similarity index 100% rename from docs/install/add-site.md rename to docs/admin-guide/add-site.md diff --git a/docs/admin-guide/index.md b/docs/admin-guide/index.md index 9ac48e4ed..cf15440e2 100644 --- a/docs/admin-guide/index.md +++ b/docs/admin-guide/index.md @@ -29,6 +29,7 @@ install-pip :maxdepth: 1 run-plone +add-site configure-zope add-ons override-core diff --git a/docs/index.md b/docs/index.md index b64c1c87d..38587e3b6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -32,8 +32,8 @@ Read the [documentation for the previous version, Plone 5](https://5.docs.plone. overview/index install/index -developer-guide/index admin-guide/index +developer-guide/index deployment/index volto/index classic-ui/index From fcd975706452aff11cf48e0c0795c12da6f99af9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 4 Nov 2024 21:10:34 -0800 Subject: [PATCH 25/32] Remove stray characters from bad merge --- docs/install/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/install/index.md b/docs/install/index.md index 1f949917a..c82a8db06 100644 --- a/docs/install/index.md +++ b/docs/install/index.md @@ -73,7 +73,6 @@ Plone trainings take place at every annual Plone Conference. (get-started-contribute-label)= -======= ## Contribute to Plone See the {doc}`Contributor Guide ` to learn how to participate in the Plone community and contribute to our open source software. From 7ccaecd273730cf4c265068a2cc32e9aa5d5b815 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 4 Nov 2024 21:21:41 -0800 Subject: [PATCH 26/32] Resolve TODOs by moving file and adding link to new choose-user-interface. --- docs/admin-guide/add-site.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/admin-guide/add-site.md b/docs/admin-guide/add-site.md index 29abafc8a..0fd93872d 100644 --- a/docs/admin-guide/add-site.md +++ b/docs/admin-guide/add-site.md @@ -7,8 +7,6 @@ myst: "keywords": "Plone 6, create, add, factory, distributions" --- -% TODO: This should move into the Admin guide once https://github.com/plone/documentation/pull/1746 is merged. - (add-a-plone-site-label)= # Add a Plone site @@ -28,8 +26,7 @@ Visit the Plone backend in a web browser. Usually it is running at http://localhost:8080/. The launch screen prompts you to choose one of the available {term}`distributions` to create a new site. - -% TODO: Add a link to the choose-user-interface doc once https://github.com/plone/documentation/pull/1749 is merged. +You can read {doc}`/conceptual-guides/choose-user-interface` to help inform your choice between Volto and Classic UI. ````{card} ```{image} /backend/upgrading/version-specific-migration/images/distribution-chooser.png From 9267edbb925208f4fee7569cc06fc52913c1a732 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 4 Nov 2024 22:16:22 -0800 Subject: [PATCH 27/32] Update glossary with Zope instance and cross-references to Zope itself. --- docs/glossary.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/glossary.md b/docs/glossary.md index 5c69b07cd..bdc61a89d 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -54,10 +54,10 @@ plone/generator-volto cookiecutter-plone-starter [cookiecutter-plone-starter](https://github.com/collective/cookiecutter-plone-starter/) creates a Plone project that you can install using {term}`Make`. It generates files for installing and configuring both the frontend and backend. - For the backend, it uses {term}`cookiecutter-zope-instance` to generate configuration files for a Zope WSGI instance. + For the backend, it uses {term}`cookiecutter-zope-instance` to generate configuration files for a {term}`Zope instance`. cookiecutter-zope-instance - [cookiecutter-zope-instance](https://github.com/plone/cookiecutter-zope-instance) is a cookiecutter template to create a full and complex configuration of a Zope WSGI instance. + [cookiecutter-zope-instance](https://github.com/plone/cookiecutter-zope-instance) is a cookiecutter template to create a full and complex configuration of a {term}`Zope instance`. CSRF Cross-Site Request Forgery @@ -144,13 +144,13 @@ Diazo Dexterity [Dexterity](https://github.com/plone/plone.dexterity) is the base framework for building content types, both through-the-web and as filesystem code. - It is aimed at Plone, although this package should work with plain Zope + CMF systems. + It is aimed at Plone, although this package should work with plain {term}`Zope` + CMF systems. Dublin Core The Dublin Core Schema is a small set of vocabulary terms that can be used to describe web resources (video, images, web pages, etc.), as well as physical resources such as books or CDs, and objects like artworks. ZMI - The Zope Management Interface. + The {term}`Zope` Management Interface. The ZMI is a direct interface into the backend software stack of Plone. While it can still serve as a valuable tool for Plone specialists to fix problems or accomplish certain tasks, it is not recommended as a regular tool for Plone maintenance. @@ -210,7 +210,7 @@ Configuration registry It is accessible from the Volto project by importing the module `@plone/volto/config` with `import registry from '@plone/volto/config'`. It contains the configuration of the Volto app. - In Plone core, [`plone.app.registry`](https://pypi.org/project/plone.app.registry/) provides Plone UI and `GenericSetup` integration for [`plone.registry`](https://pypi.org/project/plone.registry/), which in turn implements a configuration registry for Zope applications. + In Plone core, [`plone.app.registry`](https://pypi.org/project/plone.app.registry/) provides Plone UI and `GenericSetup` integration for [`plone.registry`](https://pypi.org/project/plone.registry/), which in turn implements a configuration registry for {term}`Zope` applications. component shadowing shadowing @@ -555,6 +555,10 @@ ZODB Zope [Zope](https://zope.readthedocs.io/en/latest/) is a Python-based application server for building secure and highly scalable web applications. +Zope instance + A Zope instance is a particular set of configuration for running {term}`Zope`. + A new Zope instance can be created using {term}`cookiecutter-zope-instance`. + ZPT Zope Page Template is a template language for Python. @@ -565,7 +569,7 @@ ZCA Zope Component Architecture Zope Component Architecture (ZCA) is a Python framework for supporting component based design and programming. It is very well suited to developing large Python software systems. - The ZCA is not specific to the Zope web application server. + The ZCA is not specific to the {term}`Zope` web application server. It can be used for developing any Python application. Maybe it should be called Python Component Architecture. ```{seealso} From 3d900d14205990bead4c068087eca40de69dd9f9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 4 Nov 2024 22:32:50 -0800 Subject: [PATCH 28/32] Fix cross-references --- .../upgrading/version-specific-migration/upgrade-to-61.md | 2 +- docs/conceptual-guides/make-build-backend-walk-through.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md index d353d2ed1..2ce90af1e 100644 --- a/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md +++ b/docs/backend/upgrading/version-specific-migration/upgrade-to-61.md @@ -123,7 +123,7 @@ If you have an existing Plone 5.2 or 6.0 site and you migrate to 6.1, then migra Plone 6.1 introduces the concept of a Plone {term}`distribution`. A Plone distribution is a Python package that defines specific features, themes, add-ons, and configurations that get activated when creating a Plone site. -Now it is available in core Plone as the recommended way for {doc}`creating a new Plone site `. +Now it is available in core Plone as the recommended way for {doc}`creating a new Plone site `. ```{seealso} For more information about distribution concepts, see {doc}`/conceptual-guides/distributions`. diff --git a/docs/conceptual-guides/make-build-backend-walk-through.md b/docs/conceptual-guides/make-build-backend-walk-through.md index 859852ac8..9f4e9c2f9 100644 --- a/docs/conceptual-guides/make-build-backend-walk-through.md +++ b/docs/conceptual-guides/make-build-backend-walk-through.md @@ -52,7 +52,7 @@ The command `make build-backend`: - Returning to the target `build-dev`: - - This generates the `mxdev` files as described above in {ref}`mxdev-usage-overview-label`. + - This generates the `mxdev` files as described above in {ref}`manage-backend-python-packages-label`. - Installs Plone core packages and add-ons from the files generated by `mxdev`. You can configure your Zope instance as described in the section {doc}`/admin-guide/configure-zope`. From 6fb37ee1ec657d1432b889518275a93d8a506a9f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 4 Nov 2024 23:33:23 -0800 Subject: [PATCH 29/32] Fix link --- docs/conceptual-guides/distributions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conceptual-guides/distributions.md b/docs/conceptual-guides/distributions.md index 80ff4a4bb..ed1d6d76f 100644 --- a/docs/conceptual-guides/distributions.md +++ b/docs/conceptual-guides/distributions.md @@ -53,7 +53,7 @@ Custom Plone distributions can be distributions for use by others. Examples of third-party Plone distributions include: - [SENAITE](https://www.senaite.com) -- [Quaive](https://quaivecloud.com/) +- [Quaive](https://quaive.com/) - [Portal Modelo](https://www.interlegis.leg.br/produtos-servicos/portal-modelo/) - [Portal Padrão](https://identidade-digital-de-governo-plone.readthedocs.io/en/latest/) From 585ef0a057138d4fa8ce91ef624b1caeed53b56e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 4 Nov 2024 23:42:34 -0800 Subject: [PATCH 30/32] Ignore link to static images --- docs/conf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index d79793765..721742d0e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -82,8 +82,9 @@ r"http://127.0.0.1", r"http://localhost", r"http://yoursite", - # Ignore file downloads + # Ignore static file downloads r"^/_static/", + r"^/_images/", # Ignore pages that require authentication r"https://github.com/orgs/plone/teams/", # requires auth r"https://github.com/plone/documentation/issues/new/choose", # requires auth From 0fc4efefba82c270ddbc9f8d7f3799782255a493 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 5 Nov 2024 00:57:42 -0800 Subject: [PATCH 31/32] Ignore searches on GitHub as it rate limits and times out. --- docs/conf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index 721742d0e..c253b8d93 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -92,6 +92,8 @@ r"https://opensource.org/", # requires auth # Ignore github.com pages with anchors r"https://github.com/.*#.*", + # Ignore github.com searches + r"https://github.com/search", # Ignore other specific anchors r"https://coveralls.io/repos/github/plone/plone.restapi/badge.svg\?branch=main", # plone.restapi r"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors#Identifying_the_issue", From 90f20f69e443ee73fe07d3c4d250ce76ddd2718c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 5 Nov 2024 15:35:54 -0800 Subject: [PATCH 32/32] Update docs/developer-guide/index.md Co-authored-by: David Glick --- docs/developer-guide/index.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/developer-guide/index.md b/docs/developer-guide/index.md index 867f46c58..797edd0d7 100644 --- a/docs/developer-guide/index.md +++ b/docs/developer-guide/index.md @@ -11,6 +11,12 @@ myst: This part of the documentation provides information for how to develop in Plone. +```{note} +This part of the documentation is under construction. +You can find documentation for development in various locations through the [search feature](https://6.docs.plone.org/search.html?q=development). +You can help consolidate all of development documentation here, even if it is to let us know what is missing, by [creating an issue](https://github.com/plone/documentation/issues/new?assignees=&labels=&projects=&template=new-issue-form.yml). +``` + ```{toctree} :maxdepth: 2