Upgrading Plone 5.2 to 6.0
Upgrading Plone 5.2 to 6.0#
Plone 6.0 has seen the following major changes. Some may require changes in your setup.
Plone no longer ships with the
portal_quickinstaller tool (
In existing sites, the standard upgrade will remove the tool.
This is the final step in a deprecation path that started in Plone 5.1.
Documentation of how to switch to
GenericSetup and the new installer, can be seen in Upgrade a custom add-on to Plone 5.1.
Dexterity site root#
For content types, in Plone 4 and 5 you had the option to use the old Archetypes or the new Dexterity framework. The Plone site root object was neither: it was in its own class. In Plone 6, the site root itself is a Dexterity object.
When you upgrade a site from Plone 5.2 to 6.0, at first you will see an empty site root.
Do not panic.
Your content is only temporarily invisible.
Perform the standard migration via the
@@plone-upgrade view, and your content will be visible again.
Plone 6 ships with a new React-based frontend, Volto.
When you use the
Plone package in your project, you will get the
plone.volto integration package.
This package prepares your Plone site's backend as a REST API.
The classic integrated frontend which is called "Classic UI" is still available if you are not ready for the new separate frontend.
If you choose to use Classic UI, then do not use the
To learn how to modify an existing Plone site to run with Volto, please read Migrating from Plone Classic UI to Volto.
The deprecated Archetypes content types framework is no longer supported. Add-ons that define a content type must use Dexterity instead.
Some deprecated views have been removed#
In Plone 6 some legacy view aliases have been removed. You can replace them with the new ones based on the following table:
temp_folder object in the Zope root is no longer created by default.
If the object is there, but it is broken, the standard Plone upgrade procedure will remove it.
For now, you must explicitly disable the
temp_folder if you use buildout:
[instance] recipe = plone.recipe.zope2instance zodb-temporary-storage = off
Changed templates to Twitter Bootstrap 5 markup#
Plone 6.0 means we move from Zope 4 to 5.
This drops support for Python 2.7, drops
ZServer, and removes deprecated code.
Some imports may need to change. Add-on authors should check on Plone 5.2 if their code runs without any deprecation warnings from Zope 4. If no warnings are shown, the add-on should run fine on Zope 5.
Modernize Plone default theme (Barceloneta LTS)#
The standard theme in Classic UI was updated to Bootstrap 5, CSS variables, and an icon library. If you have a theme that builds on Barceloneta, you most likely need various changes.
It may be best to start with a fresh theme, and try to keep the changes minimal. The training documentation lists three possible theming strategies:
Create a theme based on Barceloneta.
Create a theme from scratch.
Create a theme based on Diazo.
You may need to use a newer Python version. Supported Python versions are 3.8, 3.9, 3.10, and 3.11. We recommend the most recent version. See https://www.python.org/downloads/ for which Python version is still supported by the Python community.
plone.api package now has a
Add-on authors may want to use this to get, create, or delete relations.
Mockup and resource registry redone#
The compiled version is in
The resource registries and their control panel have been simplified. Add-ons for Classic UI Plone only need to register bundles, not individual resources.
Relations control panel#
Plone 6 has a new control panel for relations,
As a Manager, you may want to use this control panel to look for and fix possible problems.
Deprecated Unicode property types#
Zope 5 has deprecated the Unicode property types
If you use these in your add-on, you should switch to their standard variants
These behave exactly the same on Python 3.
Plone has an upgrade step that goes through all objects in the site, replacing the deprecated properties with the default ones.
You should avoid adding them to your code.
We have replaced
Both are used by add-ons (Python packages) to signal, with an entry point, that Plone must load the ZCML of the add-on.
In most cases, the existing entry point can stay the same.
For example in
entry_points=""" [z3c.autoinclude.plugin] target = plone """
When your package name differs from your module name, you need to specify a differently named entry point.
When your module is named
example.alternative, create this entry point:
entry_points=""" [plone.autoinclude.plugin] target = plone module = example.alternative """
includeDependencies directive is no longer supported.
It was already recommended not to use this directive, as it is too implicit.
In the ZCML files of your add-on, search for
Replace all of its instances by explicitly loading any ZCML from other packages used by the add-on.
Here is a sample change from
- <includeDependencies package="." /> + <include package="Products.membrane" />
The same change is needed for the no longer supported
includeDependenciesOverrides directive, which may be used in
You can mark fields of a content type as searchable.
You can then find an object in the search form by using any text from these fields.
For this to work, you need to enable the
plone.textindexer behavior on the content type.
For more information, see TextIndexer.
In earlier Plone versions, this feature was available in the
This was merged into Plone 6.0 core, with most code ending up in
If you have an add-on or custom code that uses the old package, then this must be upgraded. These are the needed changes:
Update the Python code of your content type code, like this:
-from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from plone.app.textfield import RichText from plone.supermodel import model ... class IExampleType(model.Schema): - dexteritytextindexer.searchable("text") + textindexer.searchable("text") text = RichText(...)
In the GenericSetup xml of your content type, use the new behavior:
<property name="behaviors" purge="false"> - <element value="collective.dexteritytextindexer" /> - <element value="collective.dexteritytextindexer.behavior.IDexterityTextIndexer" /> + <element value="plone.textindexer" /> </property>
Search for any leftovers of
collective.dexteritytextindexerin your code and replace it.
The in-place upgrade to Plone will replace the two versions of the old behavior with the new one in all content types.
Within the Plone code base there are circular dependencies.
Package A uses package B and package B uses package A.
Products.CMFPlone is the main package of Plone where everything comes together.
Products.CMFPlone depends on a lot of Plone packages.
But these packages often import code from
This is done in such a way that it works, but it creates an unclear situation and makes it hard to debug errors when they occur in this implicit dependency chain.
The solution in Plone 6.0 was to create a package called
Some often used code from
Products.CMFPlone and other packages was moved here.
Backwards compatibility imports were kept in place, so this should not cause any breakage in add-ons.
You will get warnings in your logs, unless you have silenced them.
For example when your code has
from Products.CMFPlone.utils import base_hasattr you will see:
DeprecationWarning: base_hasattr is deprecated. Import from plone.base.utils instead (will be removed in Plone 7)
If the add-on only needs to support Plone 6, you can change the code like this:
- from Products.CMFPlone.utils import base_hasattr + from plone.base.utils import base_hasattr
If the add-on needs to support both Plone 5 and 6, this works and avoids the warning:
try: from plone.base.utils import base_hasattr except ImportError: # BBB for Plone 5 from Products.CMFPlone.utils import base_hasattr
Support for modern image scales#
In Plone 5.2 the following image scales were available, with scale name, width, and height:
large 768:768 preview 400:400 mini 200:200 humb 128:128 tile 64:64 icon 32:32 listing 16:16
Plone 6.0 changes them:
huge 1600:65536 great 1200:65536 larger 1000:65536 large 800:65536 teaser 600:65536 preview 400:65536 mini 200:65536 thumb 128:128 tile 64:64 icon 32:32 listing 16:16
The biggest scale now has a width of 1600 instead of 768.
largescale was made slightly bigger: from 768 to 800.
All scales above
minihave a height of 65536. This does not mean you get an extremely high image. It means only the width is taken into account when resizing the image. This is a better fit for most modern themes.
The standard Plone upgrade only adds the completely new scales:
It leaves the other scales untouched.
This is to avoid strange differences between old and new images.
For example, old images would otherwise have a large scale with width 768, where for new images this would be width 800.
In Plone 6, we have made a split between generating a URL for an image scale and actually scaling the image. Why would you want this?
As an add-on author, you create a template and you want to show an uploaded image with the preview scale. The code would be like this:
<img tal:define="images context/@@images" tal:replace="structure python:images.tag('image', scale='preview')" />
In Plone 5 this creates a scale of the image, using the Pillow imaging library. In Plone 6, the scaled image is not yet created at this point. The scaled image is only created when the browser actually requests the image.
This is good, because for various reasons, the browser may never actually ask for this scaled image. For example, the browser may be on a mobile phone with the images turned off to prevent using costly band width. Also, when the tag contains source sets for HiDPI or picture variants, the browser may see five possible images and only choose to download one of them.
In Plone 6, when generating a tag for, as in this case, the
preview scale, a unique URL is generated, and information for this scale is pre-registered.
Only when the browser requests the scaled image at this URL, does Plone generate the scale.
This avoids generating image scales that never get used.
This performance improvement makes two other image improvements possible. These follow in the sections directly below.
Add-on authors do not have to change anything.
But it is a good idea to check how you are using images, otherwise you miss out on this improvement.
If you call the
tag method like above, you are good.
If you use the
scale method and then use its
tag method, then you should change:
<img tal:define="images context/@@images" - tal:replace="structure python:images.scale('image', scale='preview').tag()" /> + tal:replace="structure python:images.tag('image', scale='preview')" />
Alternatively, you can explicitly use the new
pre argument, but this will fail on Plone 5:
<img tal:define="images context/@@images" tal:replace="structure python:images.scale('image', scale='preview', pre=True).tag()" />
There now is an image test page that shows several scales of an image, in various modes.
In your browser, go to an image, and add
/@@images-test to the end of the URL.
Responsive image support#
Responsive image support was added with picture tags. For more information, see Responsive image support.
In an add-on nothing needs to be changed.
But if you want to use the responsive image support, you should use the
<img tal:define="images context/@@images" - tal:replace="structure python:images.tag('image', scale='preview')" /> + tal:replace="structure python:images.picture('image', picture_variant='small')" />
Store image scale info in catalog metadata#
When you add or edit an image, Plone 6 pre-registers all scales and stores information about them in the portal catalog. The catalog brain of an image then has all the needed information about each scale, especially the unique URL, width, and height. This is used on lists of images to be able to show a scale in a tag without waking up the image objects from the database. In other words, this speeds up pages that contain lots of images.
Add-on authors do not have to change anything, as this happens automatically. If you have a very special use case, you can influence this with some new adapters.
When upgrading your Plone Site to Plone 6.0, the in-place migration finds all images in your site. It then adds the scale information to the catalog. This may take a long time. You can disable this with an environment variable:
In that case, you are advised to add the
image_scales column manually to the catalog later.