Plone Upgrade Guide
Instructions and tips for upgrading to a newer Plone version.
1. Introduction
What does it mean to upgrade Plone?
This document covers the procedures and issues involved in upgrading an existing Plone installation. This involves both the upgrading of the program set, and migration of the site itself.
Generally, you will often see the word "migration" used as the word we use to describe the process of getting your Plone site from one version of a given component to a newer version. For most people, this means upgrading Plone to a newer release, for example from 2.5.x to 3.3.x.
Migration is necessary because the internals of Plone sometimes change to support new functionality. When that's the case, the content which is stored in your Plone instance may not match what the new version of the software expects. Plone has a builtin tool that migrates existing content to the new structure.
This guide describes migration in Plone, specifically how you upgrade between different versions.
Before migrating you should read this entire document to understand the potential impact migrating will have on your Plone site. In particular, read everything in the "common problems and issues" section.
The guide applies to all contemporary versions of Plone, and we have also included the older, unsupported versions for reference.
A note about version numbering and terminology
Up until Plone 2.1, the policy was that each of our major releases would be incremented 0.1, like a standard framework policy. This caused some confusion and false expectations on how complex an upgrade would be, and have since changed this policy.
Starting after the 2.5 release, we have moved to a policy that increases the version number to a .0 on every major release. This means that when we say a "major release", we are referring to a x.0 release, whereas a minor release has the version numbering 2.5.x or 3.0.x.
In addition to the general procedure there are version-specific migration guides. These guides contain more specific instructions and valuable information that has been collected from real-life migration cases.
2. Preparations
Things to do before you migrate Plone.
Gather information
- Read the "What's new in..." for your relevant plone version, and read the release notes. You'll find these in the CMFPlone directory of the distribution of the new version of Plone.
- Check for dependencies
- Read the release notes for the Plone release you are upgrading to, in particular:
- What version of Python is required?
- What version of Zope is required?
- Do you need any new python libraries?
- Make sure all the add-on products you are using have updated to support the version of Plone you are upgrading to.
- Start with the third-party products that are in use on your site. Verify that they have been updated or verified to work on the new version, and get them upgraded in your existing instance before you start the Plone/Zope/Python upgrade if possible.
- If Zope depends on a newer version of Python, install the new version of Python first.
- If the newer version of Plone depends on a newer version of Zope, you will need to install that before proceeding with the Plone upgrade.
- NOTE: Zope has it's own migration guidelines, which you will find in the release notes of the version you are migrating to. If Plone is being upgraded at the same time as a Zope version, Plone will usually handle the Zope upgrade with its own migration script.
-
Read the following files in the CMFPlone directory of the distribution of the new version of Plone you want to update to:
- README.txt
- INSTALL.txt
- UPGRADE.txt (although this usually contains only the general procedure outlined above)
- Read the release notes for the Plone release you are upgrading to, in particular:
Back up your Plone site
It's very important to back up your Plone site. You will find an excellent how-to on backing up your Plone site here.
Setup a test environment to rehearse the upgrade
Never work directly on your live site until you know that the upgrade was successful. Instead, create a test environment to rehearse the upgrade. Copy your instance into a new environment and upgrade the copy. This is a good way of working out your third party products and dependencies in preparation for the final upgrade of the live site!
3. Upgrading Plone 4 within 4.x.x series dot minor releases
Plone 4 uses buildout, which makes minor version upgrades very simple.
Plone 4.0 and above use buildout in its packaged installers. Among the many benefits of buildout is the fact that it makes minor Plone version upgrades extremely simple. Here is the general procedure, which is based on the buildout shipped with the Plone Unified Installer.
Obligatory Warning
Before performing any Plone upgrade, you should always have a complete backup of your site. See the "Preparations" section of this manual for more details.
In addition, you should check the "Version-specific migration tips" section of this manual for any notes that may apply to the specific version upgrade you're about to perform.
1) Edit your buildout.cfg file
Out of the box, Plone's Unified Installer includes a buildout.cfg (typically located at your-plone-directory/zinstance/buildout.cfg) file that contains the following parameter:
extends =
base.cfg
versions.cfg
# http://dist.plone.org/release/4.1-latest/versions.cfg
This tells buildout to get all of its package versions from the included versions.cfg file. Notice that there is another line, commented out, that points to dist.plone.org. This location will always contain the most recent versions that comprise the latest release in the Plone 4.1 series. (You can also replace 4.1-latest with 4.0-latest or 4.2-latest, or another other existing minor release in the 4.x series.)
To upgrade your buildout to use the latest Plone 4.1.x release, comment out versions.cfg and uncomment the line pointing to dist.plone.org, so it looks like this:
extends =
base.cfg
# versions.cfg
http://dist.plone.org/release/4.1-latest/versions.cfg
If you want to upgrade to a specific point release, you can substitute, e.g.
http://dist.plone.org/release/4.1.4/versions.cfg
http://dist.plone.org/release/4.2b2/versions.cfg
http://dist.plone.org/release/4.0.10/versions.cfg
Save your changes.
2) Stop Plone, Rerun Buildout, Restart Plone
Now that you've edited your buildout file, stop Plone (bin/plonectl stop), rerun buildout with the command:
> bin/buildout
This may take a few minutes as Plone downloads new releases. When buildout finishes running, restart your Plone instance (bin/plonectl start).
3) Run Migration Script
Visit your Zope instance's ZMI (http://yoursite:8080). You will likely see a message prompting you to run Plone's migration script for each site in your instance, e.g.
This site configuration is outdated and needs to be upgraded.
Click Upgrade button next to the site and the upgrade will run. Check the "Dry Run" checkbox if you want to test the migration before you execute it.
Voila! You've successfully upgraded your Plone site. Plone on!
4. Upgrade add-on products
The steps to take to migrate your third party products
- Shut down your Plone server instance.
- If you specified concrete versions of the third-party products in your buildout.cfg file (what is so-named "pinning"), like Products.CacheSetup = 1.0, update these references to point to the new versions. Without pinning, i.e. specifying only, for example, Products.CacheSetup and no version, buildout will pick the newest version of the products by default.
- Run bin/buildout. Wait until all new software is downloaded and installed.
- Start Plone again - your site may be inaccessible until we have performed the next step - don't panic :)
- Navigate to the quickinstaller in the ZMI, and reinstall or upgrade products if you can (products that support both your current
and new version of Plone). Perform product-specific upgrade procedures (if any). You will find these in the documentation of each product.
5. Troubleshooting
What to do when a problem occurs during a Plone upgrade.
When a problem occurs during the migration we recommend that you take the following steps.
Check the log files
When a site error occurs, or Zope fails to start, there's probably an informative error message in Zope's log files. Locate these log files and inspect instance.log. Ignore irrelevant warnings and search for words such as error, exception and traceback (case-insensitive).
When Zope doesn't start and there's no useful information in the log file, you can start Zope interactively and watch for error messages in the output:
bin/instance fg
You may be able to find more information on the error messages in:
- the Version-specific migration tips for your version of Plone
- the Error References
Test without customizations
When you have customized page templates or Python scripts, your changes may interfere with changes in the new version of Plone. It's important to rule out this possibility, since your customizations are unique to your site and no one on the planet will be able to help you solve it.
Temporarily remove your customizations, for example by removing your layers from portal_skins, or by removing files from these layers on the file system. If the problem disappears, you'll need to doublecheck your customizations. It's usually best to copy the original files of the new version of Plone to your skin, and re-customize those.
Test without products
Bugs or compatibility problems in products that you have installed may cause problems in Plone. Go to Site Setup > Add/Remove Products and remove (uninstall) all product that are not distributed with Plone. Remove the uninstalled products from the Products directory of your Zope instance.
If the problem disappears, you'll need to doublecheck the offending product:
- Does it support the new version of Plone, Zope and Python? Check the product's README.txt or other informational files or pages.
- Does the product require any additional migration procedures? Check the product's INSTALL.txt, UPGRADE.txt or other informational files or pages.
- Does the product install properly? Re-install it and check the install log.
Test with a fresh Plone instance
Create a new Plone site with your new version of Plone. You don't need a new Zope instance, since you can add another Plone site in the root of Zope. If the problem does not occur in a fresh site, the cause of your problem is most likely a customization, an installed product or content that was not migrated properly.
Make the problem reproducible
Before you go out and ask for help, you should be able to describe your problem in such a way that others can reproduce it in their environment.
Reduce the problem to the smallest possible domain. Eliminate products and customizations that are not part of the problem. This makes it easier for others to reproduce the problem and it increases your chances of meeting others with the same problem or even a solution. The more complex your story is, the more likely that it is unique to your situation and inpenetrable to others.
Ask for help on a mailing list
Ask for help on the Plone setup list. Be sure to:
- Provide relevant source code for your customizations that are part of the problem.
- Describe the exact configuration, software versions, migration history, error messages and so on.
Report a bug
Once you have investigated, analyzed, identified and confirmed the cause of your problem and you are convinced it's a bug (rather than an X-file), go to the appropriate bug tracker and report it:
- Products: the README usually tells how to report bugs
- Plone Issue Tracker
- CMF Issue Collector (if you don't know what the CMF is, don't report bugs)
- Zope Issue Collector
Do not use the bug trackers to ask for help. First analyze your problem and assert that it's a bug before you report it.
6. Version-specific migration procedures and tips
In addition to the general procedure described in the previous sections, this section provides version-specific procedures and tips. If your migration does not involve a version pair specified here, then you may follow the general procedures alone.
6.1. General advice for upgrading pre-2.5 releases to the latest release
To upgrade a very old version of Plone (2.1, 2.0 or 1.0), we recommend that you upgrade to Plone 3.x first, and *then* upgrade to later releases.
In order to keep the Plone codebase tidy, we periodically remove the code that handles upgrades from very old Plone versions.
As a result, Plone 4.x supports upgrades directly from Plone 2.5 and Plone 3.x, but not from older versions such as Plone 1.0 and Plone 2.1. If you need to upgrade from an older version of plone, we recommend that you first upgrade to the most recent release of Plone 3.x, and then to Plone 4.x.
As an example, let's say you're running an ancient Plone 2.1 install. The approach to upgrade to (for example) Plone 4.0 would then be:
- Back up your setup.
- Move your Data.fs (and upgraded add-on products) to a Plone 3.3.x install.
- Follow the general upgrade instructions outlined earlier in this manual.
- Once you have a running Plone 3.3.x-based version of the install, get the latest 4.0.x release, and upgrade from Plone 3.3.x to Plone 4.0
Upgrades from Plone versions earlier than 2.1 can be handled similarly; however, in this case you should upgrade to Plone 2.5 as the intermediary version before going to Plone 3 or Plone 4, since Plone 3.x doesn't support upgrades from Plone less than 2.1.
6.2. Upgrading from Plone 1.0 to 2.0
Version-specific procedures and tips for migrating Plone 1.0 to 2.0.
The changes made to Plone between 1.0 to 2.0 are fairly complex. Before migrating you can read this document to understand the potential impact migrating will have on your website. We suggest to follow standard practices: backup your Products and Data.fs file(s), do the actual migration on a test instance., etc. Another note is that Plone's migration are probably not perfect - this is hard to guarantee, since we can't predict just how you have changed your system.
If you have a big site running Plone and want a painless transition to the much-improved version 2.0, we suggest that you hire a company that can do the migration properly for you. Send a mail to the Plone Developer mailing list, and we can recommend a company in your area if needed.
The migration tool handles most cases, but your mileage may vary. Heavily customized sites should factor in some time to do the transition.
Side Effects Moving to 2.0
* Plone CSS has radically changed.
* Plone Templates have radically changed.
* Plone 2.0 Tools Tools for Plone have changed
* Plone 2.0 Group User Folder the User Folder for Plone has changed
* See the What's New in Plone 2.0 Guide for more information about what has changed.
Template/CSS Changes
The templates and CSS have been refactored and reorganized to be leaner, more efficient and more logically laid out. The CSS class names have been changed to be consistent and to provide easier customization. Therefore, if your site customized the templates or CSS, you will have to examine how your changes are affected by the new templates and CSS.
* ploneDeprecated.css
* About the tableless layout
* base_properties vs. stylesheet_properties
* Form changes: New Forms Style and How to Convert from the Plone 1.0 forms format
* CSS Nameageddon - the CSS class names have changed from Plone 1 to Plone 2
base_properties
Plone 1 shipped with a property sheet called 'stylesheet_properties', that enabled you to change your site in a quick and easy way.
In Plone 2, we have stripped this down a bit, and changed its name to 'base_properties' to better reflect what it's for.
The reason for this was that the 'stylesheet_properties' was kind of a half-way mix of color properties and CSS, and you could do much more than simple color changes with it. This complicated things for the CSS people, and thus we decided to keep the separation cleaner, and have only base properties in the variables.
It's not possible to do a perfect 1:1 mapping between the two, and you might have to resort to a few simple CSS rules to replicate what you had in Plone 1. The good news is that it's much more flexible and powerful this way.
The best approach to converting to the new scheme is to start with the existing 'base_properties', and move your color and border values over one by one until you have something that resembles your old layout.
Lexicons
lexicon in portal_catalog is set as plone_lexicon. Look at your ZCTextIndex indexes to see what lexicon they are looking for. On plone.org, we needed to rename the lexicon to zc_lexicon (or we could have recreated the ZCTextIndexes and specified whatever lexicon you have.) Even if your ZCTextIndex indexes are looking for the right index, you may benefit from re-indexing those fields.
Special Note about the Windows Installer
You have to uninstall previous Plone versions and delete the Plone service before you can install Plone 2 successfully on Windows XP. The service doesn't delete by itself when you uninstall.
6.3. Upgrading from Plone 2.0 to 2.1
Procedures and tips to migrate your site from Plone 2.0 to 2.1.
A note about migration and version numbering
Plone has changed significantly infrastructure-wise with the jump from Plone 2.0 to 2.1. Plone 2.1 represents 18 months of active development and improvements, and is a much more scalable and powerful platform with the 2.1 release.
Some people are confused by the low version number increase, and mistakenly assume that it is a minor upgrade. It is not, far from it.
Up until Plone 2.1, the policy was that each of our major releases would be incremented 0.1, like a standard framework policy. We understand that this is somewhat confusing, and have since changed this policy. The Plone Team aims to release a new version roughly every 6 months, so we have moved to a policy that increases the version number by 0.5 on every significant release.
We have done this to better reflect the enormous amount of work that goes into each release, and to better illustrate what you can expect from a release.
The main point here is that even if an upgrade from 2.0 to 2.1 sounds minor, in this particular case it is not. The entire content type infrastructure has been rewritten, and all your content needs to be transferred to the new types, so there will most likely be some pain involved on some level — be it third-party products, templates that need to be re-customized, or actual bugs in the migration machinery (which have mostly been ironed out with the 2.1 and 2.1.1 releases).
About the migration
Please note that it is difficult to predict how well migration will work, since we can't know just how you have changed your system. Plone is a very flexible system, but when migrating this will affect the outcome based on what you changes you have made to your system.
- If you have a standard Plone site with simple customizations, it will likely work very well.
- If you have installed and depend on a lot of third-party products produced by developers outside the Plone Team, it's hard to say something definite - make sure the products you depend on are certified to work with Plone 2.1.x. **Special note about SpeedPack:** You should uninstall this product, as most of the improvements done in this product are now part of Plone, and as a result, it's no longer necessary (and it doesn't work on Zope 2.8).
- If you have a big site running Plone and want a painless transition to the much-improved version 2.1, we suggest that you hire a company that can do the migration properly for you. Send a mail to the "Plone Developer mailing list":/contact#developers, and we can recommend a company in your area if needed.
The migration tool handles most cases, but your mileage may vary. Heavily customized sites should factor in some time to do the transition.
For Plone 2.5 (our next upcoming release), there are substantial improvements to the architecture that will ease migration in the future, as well as providing good tools for exporting and importing content and configurations.
Plone 2.1.2 and later releases also includes significant improvements to the migration machinery based on feedback we got from people doing migrations, so if migrating your site using the Plone 2.1 or 2.1.1 release didn't work out for you, please give the new version a try.
Performing the migration
Before you start the migration, you should decide what approach you want to use. There are two common ways of migrating:
1. Migrating your site content, products and customizations in-place.
2. Exporting your content, creating a fresh Plone 2.1 site, importing your content.
The in-place migration is more comprehensive, and hence more error-prone, especially if you have misbehaving third-party products or very old Plone instances. If your content is the most important thing for you, and you don't mind applying your configuration settings and simple customizations again, exporting all your content folders followed by an import into a clean instance might be a better approach for you. This procedure is described in the "importing Plone 2.0 content into 2.1 FAQ":/documentation/faq/importing-2.0-content-into-2.1. Please note that this should only be done if you are experiencing problems and as a last resort (or simply want to start with a clean site but keep your content) — for most people, in-place migration is the way to go.
The in-place procedure is the usual one for Plone migrations, a quick overview of the steps:
1. If you want to upgrade from Zope 2.7 to Zope 2.8 in this transition, we advice you to **stay with Zope 2.7 until you have completed the Plone part of the migration**, *then* upgrade to 2.8. Zope 2.8 includes major changes and improvements, and trying to upgrade both Zope and Plone in the same operation is not recommended. Both Zope 2.7 and Zope 2.8 are supported platforms for Plone 2.1.x, though. As a rule of thumb, always start at the top with upgrades, and work your way down — upgrade Products, then Plone, then Zope, then Python.
2. Make sure the third-party products you use have been updated or verified to work on Plone 2.1. Upgrading to 2.1 if the products you are using do not support it is a frustrating experience.
3. Install the new Plone version in a clean location, you should stick with the same major version of Zope (e.g. going from Zope 2.7.3 to 2.7.5 is OK, going from 2.7.x to 2.8.x is not recommended until the Plone part of the migration is done).
4. Move over your 'Data.fs' and any Products / External Methods to the new instance.
5. Start the new Zope/Plone
6. Log in to the ZMI as a 'Manager' user.
7. Go to 'portal_migration'
8. Click the migrate button and wait for the output from the migration process. This can take a considerable amount of time depending on your site, since all content is being re-created with the new content types, and re-cataloged.
Common problems and issues
- Several "new" tabs will appear at the top of the site. This is due to a policy change in how Plone constructs navigation. Plone 2.1 and up will automatically make tabs from the folders in the root, and doesn't require you to manually create them in the portal_actions tool anymore. To fix this, you can either:
- Go in and delete your portal_actions entries to only use the root folders (the folders also have individual visibility settings in the Properties tab of each item). This is the recommended approach unless you have global tabs leading deep inside the site, or:
- Turn off the automatic tab generation in the 'Site Setup' → 'Navigation Settings'. This will make the global tabs behave the way they did in 2.0.
- All the content items and folders **that you have the permissions to view** now show up in the nav tree - if you want the old behavior from Plone 2.0 back, where only folders show up — and only those who are published — you can now control the navigation setup in 'Site Setup' → 'Navigation Settings'.
- If you have an item with the short name 'events' or 'news' in the root of your site, they should be renamed before starting the migration - since this can cause problems with the migration to the new Smart Folders that list these.
- If you get 'AttributeError: referencebrowser_startupDirectory', you are unpacking the Plone tarball with WinZip, which mangles long file names and has a lot of other problems. Get a proper unpacking tool like WinRAR instead.
- One of the problems that people run into during migration is third-party products they have installed that didn't clean up after themselves, or that left behind "dead" content when uninstalled. This can trip up the migration process. Here is a simple script that can list content with no associated product, so you can remove the defunct objects. To use it, create a 'Script (Python)' from the ZMI add menu in the root of your Plone site, paste in the code from this file, click 'Save' and then click the 'Test' tab to run the script. It should list dead object locations, so you can go and delete them manually if needed::
portal_types = context.portal_types.objectIds()
print "Dead Content Type Inspector"
print
for i in context.portal_catalog.uniqueValuesFor('portal_type'):
if i in portal_types: continue
print i
results = context.portal_catalog(portal_type=i)
for i in results:
print i.getURL()
print
print
return printed
- Another error that was often encountered in Plone 2.1 and 2.1.1 was that some objects weren't converted to the new Archetypes-based types. If you get: "maximum recursion depth exceeded" on viewing your site after the migration, the folders/objects are most likely still CMF objects, not Archetypes objects. Plone 2.1.2 includes a fix that tries to work around this problem. (The reason this exists in the first place seems to be bad behaviour introduced in the Plone 2.0 Release Candidates and subsequently fixed before the 2.0 final release, but some people still have content created with the Release Candidates.) Also note that this error message can show up if you customized a 2.0 'document_view' template and are trying to use it with Plone 2.1.
- If all (or some of) the migrated content are owned by the person doing the migration instead of the original author, that means that Plone was unable to look up the owner info while migrating. The cause of this is normally that your users are stored in LDAP and you haven't set up the connection before doing the migration. Another possibility is that your users are defined outside the Plone site.
- If you don't get any images in the image views or thumbnails in the summary listings: PIL is now a dependency, and you will not get image scaling if it is not installed. Also, you need to make sure zlib (for PNG support) and libjpeg is installed before you install PIL. More information "can be found here":/documentation/error/no-image-resizing.
- If your content column is missing on all pages, one of the portlets you have set up is broken. Some versions of Plone (including the RCs of 2.1.2) had a bug where it would just stop rendering the content column instead of giving you an error if one of your portlets break.
- Some people are also confused about the behavior of security in 2.0 vs. 2.1: A bug in Plone 2.0 made it so that it **seemed** to be the case that if any folder along the path to an item was private, that item could not be viewed, regardless of its state. Workflows in Plone behave in a different way, though - allowing you to have a folder that is private, and have a published item inside it that is accessible (but the folder will be inaccessible). If you want your permissions to inherit down the path, you'll have to make some changes to the workflow, "documented here":/documentation/how-to/make-permission-settings-inherit. The reason this seemed to work in Plone 2.0 was a bug in the breadcrumb handling code, and the object wasn't protected there either, but erroneously seemed to be.
- If you get the error 'AttributeError: _length', you are upgrading to Zope 2.8, and you will need to call 'manage_convertIndexes' on all catalogs that are not in the root (CMFCollector catalogs etc). Third-party products sometimes have their own catalogs, check with the product maintainer about this. See the section "Upgrading from Earlier Versions of Zope" in the file 'Zope-2.8.4-final/doc/FAQ.txt'.
- If LiveSearch doesn't work or you have other symptoms that looks like the catalog isn't working properly, check out the "FAQ on disappearing catalogs":/documentation/faq/catalog-disappears
- If you get 'AttributeError: toPortalTime' from a third-party product, it needs to update itself to use 'toLocalizedTime' instead. 'toPortalTime' was deprecated in Plone 2.0, and is removed in Plone 2.1.
- If for some reason some of the original tools are corrupted or not working properly, you can copy in fresh instances from a newly-created Plone site. I will show an example where the 'portal_form_controller' tool is not present in the migrated site. Typically you would get AttributeError: portal_form_controller as an error message. In this example, {Zope} represents the Zope root (for example, localhost:8080)and {Plone} represents your Plone site:
1. Go to 'http://{Zope}/manage_main' and log in with a Manager user.
2. Add Plone Site from the pulldown menu
3. Call it 'TempPlone'
4. Once the Plone site is created, go to 'http://{Zope}/TempPlone/manage_main
5. Check the box next to 'portal_form_controller', and click 'Cut' at the bottom of the page.
6. Go to http://{Zope}/{Plone}/manage_main
7. Make sure there is no 'portal_form_controller' in the list. If there is, delete it.
8. Click the 'Paste' button at the bottom of the form.
9. Your site now has a fresh 'portal_form_controller' from a new Plone 2.1 site, and should work properly. You can now delete the 'TempPlone' instance.
Additional notes
- If you still have problems, create an issue in the "issue tracker":/collector - make sure you use the Upgrade / Migration topic, and remember to search before submitting an issue to minimize duplicates. Make sure you provide as much detail as possible on your configuration and setup, so we can better help you.
Tip: How to re-customize your templates
If you have done significant changes to the Plone 2.0 templates (functionally, that is - the CSS classes are mostly the same as in 2.0), you may have to re-apply these customizations to the 2.1 templates. The best way to do this is:
- Have one directory with the original Plone 2.0 templates
- Compare your customized templates with the original Plone 2.0 ones (a visual diff tool is useful for this - we recommend Meld for Linux, FileMerge (included in XCode) for Mac OS X, and WinMerge for Windows)
- Apply those changes to the 2.1 templates. Of course, your customizations should not touch the original Plone 2.1 files, so make sure you place your customized templates in a file system Product, or in the 'custom' directory in 'portal_skins'.
Postscript
This document was written as an attempt to collect all the relevant information about migrating from 2.0 to 2.1 in one location. It would be impossible without all the hard-working people in the Plone Team writing the migration code (which is a boring and complex task) in the first place, and the helpful people on the "Plone Setup":/contact#setup list, who have helped a lot of people migrate successfully. You all rock!
— "Alexander Limi":/author/limi
6.4. Upgrading from Plone 2.1 to 2.5
Version-specific procedures and tips for the migration of Plone 2.1 to 2.5.
There are no version-specific procedures or tips for the migration of Plone 2.1 to 2.5 at this time. We expect the general procedure outlined in this manual to be sufficient.
6.5. Upgrading Plone 2.5 to 3.0
Upgrading your site and your products from Plone 2.5 to Plone 3.0.
6.5.1. Upgrading a Plone 2.5 site to 3.0
Tips and issues when upgrading your site from Plone 2.5 to 3.0
- To migrate from Plone 2.5 to 3.0, please follow the steps outlined in the General approach to upgrading.
- One thing to make sure you have right is that Plone is now not only files in the
Products directory, but also modules insidelib/pythonin your instance. If you're using the installers, this is taken care of for you, but if you're doing it manually, make sure thelib/pythoncomponents are in the right location.
Third party products
If you have installed and depend on a lot of third-party products produced by developers outside the Plone Team, it's hard to say something definite - make sure the products you depend on are certified to work with Plone 3. GroupUserFolder is NOT supported! (NOTE: It may not be possible to upgrade a site using GRUF with external user folders such as LDAPUserFolder. In those cases it is advised to create a new site and move the content over manually.)
If you have a big site running Plone and want a painless transition to the much-improved version 3, we suggest that you hire a company that can do the migration properly for you. Send a mail to the Plone Developer mailing list, and we can recommend a company in your area if needed.
Notes on Zope migration
Migration from Zope 2.8.7 or 2.9.5 to Zope 2.10.x is mandatory but Plone 3 does not run natively on Zope 3. If you are upgrading from Zope 2.8.7 and you have a separate Five product you need to delete the Five product from your product directory before your upgrade.
Zope 2.10.x requires Python 2.4.3+ (Python 2.4.2 is still acceptable). Also mandatory is Python Imaging Library 1.1.5 or newer, Python ElementTree.
Caching
* Caching related changes required (or maybe none!)
6.5.2. Updating add-on products for Plone 3.0
Plone 3.0 ships with new releases of Zope, CMF and Archetypes. When any framework updates, some things will be removed or changed. This is a list of the most common updates that need to be applied by product authors to ensure that their products work on Plone 3.0.
6.5.2.1. General product development and migration tips for Plone 3.0
Before we get started on the specific tips for how to update your product to work with Plone 3, let's mention some general recommendations that might save you time when updating your product in the next versions of Plone (3.5 and 4.0).
Depending on your product, it might be hard to include compatibility for both Plone 2.5 and Plone 3.0 in the same product. There are several reasons for this, but the main ones are:
- The workflow definition standard in CMF has changed
- The new portlet infrastructure (although it does support old-style portlets, performance will suffer)
- The introduction of viewlets as the main way to render content fragments in the layout
So, the general recommendation is:
- If your product is more complex than a simple type, create two releases — one for Plone 2.5 and one for Plone 3.0.
- If you used ArchGenXML to create your product, you should be able to regenerate your product from the UML model to get a Plone 3.0-compatible version.
Tip
* To further future-proof your product (for Plone 3.5 and 4.0), try the following:
* Start Zope in debug mode using 'zopectl fg' and use your product normally. Check if it outputs any deprecation warnings to the log window.
* Disable the 'plone_deprecated' skin layer and make sure your application still runs without it (this disables deprecated methods and deprecated CSS styles)
Other recommendations and suggestions
* You can use the contentmigration product to write migrations for your own products. More information on this product can be found in the "RichDocument tutorial":/documentation/tutorial/richdocument/migrations/
* A lot of the new components use Zope 3 views instead of templates. These can be customized through-the-web using the 'portal_view_customizations' tool.
* Do not ever rely on the JS libraries in Plone being the same across releases. Use the KSS abstractions, the underlying implementation might (and will!) change.
These things are not mandatory yet, but represent best-practice recommendations that will save you from updating these parts in the future:
* QuickInstaller-based installation should use GenericSetup profiles instead
* use events instead of manage_ methods (which will probably disappear in plone 3.5 or 4.0)
* Packaging technology:
* Use python packages instead of Zope products
* Ship packages as eggs and register them with the "Python Cheese Shop":http://cheeseshop.python.org/
* Use "Python Paste":http://pythonpaste.org/ to create new packages
6.5.2.2. CMFCore.permissions import syntax change
In later CMF releases, the way to import the permissions module has changed. Here's how to update your product to support both the new and the old-style syntax.
Typical error message when starting Zope::
File "Products/PloneHelpCenter/content/HelpCenter.py", line 29, in ?
from Products.CMFCore import CMFCorePermissions
ImportError: cannot import name CMFCorePermissions
What's causing it:
The following line is a common statement to get access to the permissions module, typically in the '__init__.py' file::
from Products.CMFCore import CMFCorePermissions
To make this work with both the new way of importing it and fall back to the old way if you're running an older version, replace the above with::
try: # New CMF
from Products.CMFCore import permissions as CMFCorePermissions
except ImportError: # Old CMF
from Products.CMFCore import CMFCorePermissions
Then you should be all set, and be able to support multiple versions with your product. Note that the try/except block is only necessary if you want to support Plone 2.1, if you're targeting Plone 2.5 and above, you only have to do the variant listed under "New CMF" in the example above.
To see a live example of this change, consult "Poi changeset 40594":http://dev.plone.org/collective/changeset/40594#file1.
6.5.2.3. Transaction module is no longer implicitly in Archetypes
In Archetypes 1.3 and 1.4, we imported transaction in the main module to work around a Zope 2.7 issue. Since Zope 2.7 is no longer a supported release, this is no longer the case in Archetypes 1.5 (which is what ships with Plone 3.0). Here's how to update your code.
Typical error message when starting Zope::
from Products.Archetypes import transaction
ImportError: cannot import name transaction
Archetypes no longer imports transaction, so you will have to do it in your own module now, if you are using it. Change occurences of::
from Products.Archetypes import transaction
to::
import transaction
For a live example, see `Poi changeset 40594 <http://dev.plone.org/collective/changeset/40594#file3>`_.
6.5.2.4. get_transaction module rename
Zope has changed their syntax for getting transactions, and it has been deprecated in the the previous Zope releases for a while now. Zope 2.10.x (which is what Plone 3.0 runs on) removes the old syntax, so you have to update your code accordingly. Here's how.
Typical error message::
NameError: global name 'get_transaction' is not defined
Just to show you a complete traceback of how this might look, here's the full thing as seen in a typical product install, where it is common to use subtransactions (for completeness and search engines)::
2007-04-12 23:12:01 ERROR Zope.SiteErrorLog http://localhost:8080/nu/portal_quickinstaller/installProducts
Traceback (innermost last):
Module Products.CMFQuickInstallerTool.QuickInstallerTool, line 381, in installProduct
- __traceback_info__: ('Poi',)
Module Products.ExternalMethod.ExternalMethod, line 231, in __call__
- __traceback_info__: ((<PloneSite at /nu>,), {'reinstall': False}, (False,))
Module /Users/limi/Projects/Plone/3.0/Products/Poi/Extensions/Install.py, line 65, in install
NameError: global name 'get_transaction' is not defined
/Users/limi/Projects/Plone/3.0/Products/CMFQuickInstallerTool/QuickInstallerTool.py:409:
DeprecationWarning: This will be removed in ZODB 3.7:
subtransactions are deprecated; use sp.rollback() instead of transaction.abort(1),
where `sp` is the corresponding savepoint captured earlier
transaction.abort(sub=True)
To update this, replace::
get_transaction().commit(1)
with::
transaction.commit(1)
(keep the '(1)' part if it already exists in the code, omit it otherwise)
You might have to add an 'import transaction' statement at the top of your file if you haven't imported it already.
For a live example, see the Install.py part of "Poi changeset 40594":http://dev.plone.org/collective/changeset/40594#file0.
6.5.2.5. ContentFactoryMetadata deprecation
CMF deprecated this call a while back, and Plone 3.0 is the first version that ships without this. Here's how to update your product to use the new syntax.
Typical error message::
Error Type: exceptions.ImportError
Error Value: cannot import name ContentFactoryMetadata
What causes this? Somewhere in your code, you have something like::
from Products.CMFCore.TypesTool import ContentFactoryMetadata
Update this to::
from Products.CMFCore.TypesTool import FactoryTypeInformation
instead, and you should be good to go. This change should work all the way back to Plone 2.1.
For a live example, see "DataGridField changeset 7901":http://dev.plone.org/archetypes/changeset/7901.
6.5.2.6. Update your workflows to use GenericSetup profiles
To install workflows in Plone 3.0, you have to make use of CMF's GenericSetup profiles. Installing workflows in any other way is not supported, unfortunately — there are architectural changes in CMF that cannot support both approaches at the same time.
Installing workflows via GenericSetup will make your product work only on Plone 2.5 and upwards, so make sure you create a special release/branch if you want your product to still work on Plone 2.1/2.0 (which are unsupported releases when Plone 3.0 is released).
Typical error message that indicates that you are trying to install workflows not using GenericSetup::
ImportError: cannot import name addWorkflowFactory
For existing workflows, the easiest way to make the product install use GenericSetup for workflows is:
- Install your product (and its workflows) using Plone 2.5.
- Using the 'portal_setup' tool in the ZMI, export a snapshot of the current site profile:
- Click the 'Export' tab.
- Select the parts you want to export the configuration for (in this case, 'Workflow Tool').
- Click the 'Export Selected Steps' button.
- You will now get a tar file named something like 'setup_tool-20070424225827.tar'.
- Unpack the tar file, and put the resulting files and directories in a directory 'profiles/default/' in the root of your product.
- Remove the workflow directories in 'workflow/' that are not part of your product, and edit 'workflows.xml' so that it only has the information for your workflows. See "Poi changeset 41071":http://dev.plone.org/collective/changeset/41071 for an example.
- Delete your old '.py'-based workflow definitions in 'Extensions', but make sure you keep any workflow scripts, since these will be referenced from the profile definitions.
- Add a 'configure.zcml' file in the root of your product that registers the default profile. See "Poi's configure.zcml":http://dev.plone.org/collective/browser/Poi/branches/plone3-support/configure.zcml?rev=41071 for an example.
- Remove the redundant code from 'Extensions/Install.py' and add the boilerplate code to invoke the GS setup, see "Poi changeset 41071":http://dev.plone.org/collective/changeset/41071 for an example.
This process is also the same for any code you want to move to GenericSetup, in the Poi example, we also moved the catalog metadata and various other things to use GenericSetup profiles, and could get rid of most of 'Install.py' in the process.
6.5.2.7. Portlets have a new infrastructure
In Plone 3.0, portlets are no longer simple page templates, but objects with behaviour, logic and possibilities for advanced behaviour like per-portlet caching.
Portlets have been re-implemented using the Zope 3 component architecture. Change custom portlets to use plone.app.portlets if possible. Check the Portlets Developer Manual to learn about the new portlets architecture.
Old portlets are supported via a fallback mechanism called Classic Portlet; the portlet management screen has functionality for doing inline migration for old portlets. Note that using the old portlets mechanism will affect your site performance negatively, since they will load up the old global_defines.
How to add a Classic Portlet
You will see in the Add portlet pull-down menu on the Manage portlets page an item called Classic Portlet. This item allows you to use portlets created for earlier versions of Plone.
For instance, suppose you have a Classic Portlet that you have created in your-site-instance/portal_skins/custom in the Zope Management Interface (ZMI) that displays "Hello world", using a Page Template named portlet1 with the following code:
<html> <body> <div metal:define-macro="portlet"> <p>hello world</p> </div> </body> </html>
Here's how you can include this portlet in your site:
- Login as an user with the Manage Portlets permission.
- Click the manage portlets link.
- Select Classic Portlet from the pull-down menu.
- Type the template id in the Add Classic Portlet form. In the example, portlet1.
- Leave the macro as portlet.

- Click save.
This is all you have to do to add the Classic Portlet to your folder, page, or content type.
6.5.2.8. main_template now uses Zope 3 viewlets
Plone 3 has switched to use Zope 3 viewlet components instead of the old macro include approach. Any customizations of main_template.pt or header.pt will need to be updated to use the new approach.
If have previously shipped customized versions of templates like header.pt, viewThreadsAtBottom.pt or global_contentmenu.pt to get things into the page, please switch to viewlets instead, as it makes it much easier for multiple products to co-exist without stepping on each others changes.
Documentation and examples can be found in "this tutorial":http://plone.org/documentation/tutorial/customizing-main-template-viewlets.
6.5.2.9. Plone 3 does not create member folders by default
With release 3.0, member folders are optional, and not created by default. This means that you can't rely on member folders to store data in or in any other way assume that there will be a members folder present.
While this was always considered bad practice, it's now official. Don't do it. :)
6.5.2.10. Using a tableless layout
The languishing tableless version of the Plone default theme has finally been removed from Plone 3.0. However, a product exists which can be used as a substitute.
For people who want to use tableless, you can simply install the `Plone Tableless <http://plone.org/products/plone-tableless/>`_ product on top of your site.
If you are submitting a theme to plone.org for public consumption, please specify this as a dependency in your theme product's README.txt file.
6.5.2.11. Document Actions now use Zope 3 viewlets
If you were modifying or shipping custom templates for the document actions area of a Plone page, now's the time to stop.
The new approach uses viewlets, and its default position has also been moved to the bottom of the page. It also defaults to a text-based representation instead of the icons that it was using earlier, since document actions are often too abstract to create good icons for.
6.5.2.12. Products installing workflows may need to add permissions
If your product wants to make use of the new "Editor" role that ships with Plone 3, you will have to add explicit permissions to any workflows you add.
The new "Editor" (aka. "Can Edit" on the Sharing page) in Plone 3.0 makes it easy to let people collaborate on content authoring. In some cases, editing also means the ability to add new objects inside the object people are editing.
For this to work, third party content types that add custom workflows will have to either use one of the standard "add content" permissions or explicitly give Editor the Add portal content role.
See "Ticket #6265":http://dev.plone.org/plone/ticket/6265 for the changeset and full explanation.
6.5.2.13. Indexes declared in Archetypes schemata need to be moved to GenericSetup
If you have declared indexes or metadata directly on the Archetypes field declarations, and you are using GenericSetup to install your types/FTIs, you will need to move them to GenericSetup.
This applies if you have moved from using 'install_types()' in 'Extensions/Install.py', to installing new content types/FTIs with GenericSetup using a 'types.xml' import step.
For each field that specifies an 'index', like this example from "PoiIssue.py r40594":http://dev.plone.org/collective/browser/Poi/trunk/content/PoiIssue.py?rev=40594#L77
::
StringField(
name='issueType',
index="FieldIndex:schema",
widget=SelectionWidget(
label="Issue type",
description="Select the type of issue.",
label_msgid='Poi_label_issueType',
description_msgid='Poi_help_issueType',
i18n_domain='Poi',
),
enforceVocabulary=True,
vocabulary='getIssueTypesVocab',
required=True
),
…you need to move the creation to catalog.xml with GenericSetup. If there is 'index="FieldIndex"', that means you need a new index, of type FieldIndex, with the name being the name of the accessor method::
6.5.2.14. The "Sharing" tab is now a global action
You should no longer have a 'sharing' action in the portal_types entry for a custom content type
The "Sharing" tab now points to the '@@sharing' view, and is defined as a global action in the 'object' category. If you have a custom content type and you have set up the 'local_roles' action, which would normally be pointing to the 'folder_localrole_from' template, you should remove it. It will be removed from existing, installed types during migration.
If you do not remove the action, the user will see two "Sharing" tabs.
For an example of the canonical set of actions and aliases, see "the GenericSetup definition of the Document FTI":http://dev.plone.org/plone/browser/CMFPlone/trunk/profiles/default/types/Document.xml. Of course, you may not need the 'References', 'History' or 'External Edit' actions in your own types.
6.5.2.15. Multi page schemas
By default, Archetypes fields in different schemas in Plone 3.0 will be loaded all at once, without page reloads between the 'schematas'.
In Plone 3.0, all fields from all schematas will be loaded at once. If you depend on your schematas (fieldsets) to be processed one page after the other, you'll need to mark your Archetypes content type that uses it (not the schema itself) with the IMultiPageSchema interface.
The interface lives in Products.Archetypes.interfaces.IMultiPageSchema. The code to mark your content type would look like this:
from zope import interface from Products.Archetypes.interfaces import IMultiPageSchema # ... interface.classImplements(MyContentType, IMultiPageSchema)
6.5.2.16. Enable inline editing (aka. QuickEdit)
Once you have your product updated, you might want to add support for inline editing of your type. Fortunately, this is very easy.
Adding inline editing and validation support to your view templates is as easy as calling the Archetypes widgets in view mode. As an example, consider the following typical code from Plone 2.5::
Variable goes here
Now, to render the same thing, with an h1 tag and a class on it, you do::
Variable goes here
This will keep whatever tags and styling you want around the item, and render the inline editing inside of it. It's also backwards compatible with earlier Plone versions — although these don't get the inline editing, obviously.6.5.3. Updating 2.5.3 to 3.0.3
Specific steps (for review) on updating a Plone 2.5.3 site to 3.0.3 on Linux using the Universal Installer package.
6.5.3.1. Migration Procedure
Specific steps (for review) for migrating a Plone 2.5.3 site on Linux to 3.0.3. These steps assume a previous 2.5.3 installation in the folder /var/plone/, which should be modified if necessary to suit your environment.
- Download and un-archive the Plone 3 universal installer package for Linux.
- Modify the install.sh script to point the PLONE_HOME variable to /var/plone/
- In the existing Plone site, take note of any non-Plone products that need to be moved to the upgraded instance.
It is advisable to un-install any non-essential third-party products before migrating to a new version. In most cases, products are the biggest obstacle to migrating a site, and weeding out unnecessary products can save a great deal of time and frustration. These products can be re-installed as new packages after migration.
It also seems necessary in some cases to remove installed caching objects (CacheFu), uninstall the caching products, and install new versions of the products and create new caching tools after migrating.
- As the root user (or with "sudo"), shut down the existing Plone/Zope/Zeo cluster:
/var/plone/zeocluster/bin/shutdowncluster.sh
- Move /var/plone/ to a backup folder, such as /var/plone253/
- Run the Plone 3 install.sh script with the "zeo" cluster option:
./install.sh zeo
- Start the new cluster:
/var/plone/zeocluster/bin/startcluster.sh
This can take some time, as a new Plone site is now created as part of the process. - Log into the ZMI as the "admin" user, using the password specified in /var/plone/zeocluster/adminPassword.txt:
http://localhost:8080/manage/
Once logged in, you may want to change the admin password to something more memorable (yet still secure) for future use:
http://localhost:8080/acl_users/users/manage_users?user_id=admin&passwd=1 - Stop the new cluster:
/var/plone/zeocluster/bin/shutdowncluster.sh
- In /var/plone/zeocluster/server/var/, create a backup/ folder, and move all existing contents to this new folder:
cd /var/plone/zeocluster/server/var/
mkdir backup
mv Data.fs* backup/Note that this step isn't completely necessary: you could just delete the existing files, but it's nice to back-up a working configuration in case things go wrong later.
- Copy Data.fs from the old instance to the new installation, and ensure the permissions are correct:
cp /var/plone253/zeocluster/server/var/Data.fs .
chown plone:plone Data.fs - Start the new cluster:
/var/plone/zeocluster/bin/startcluster.sh
- Log into the ZMI as the "admin" user:
http://localhost:8080/manage/ -
Note: this step is here presently only for the purpose of a full procedure review: it may be bug-related and should not be performed as part of a base migration. Try this only if all else fails.
In the ZMI, at the Plone site root, delete the following objects:- content_type_registry
- mimetypes_registry
- portal_transforms
-
Note: this step is here presently only for the purpose of a full procedure review: it may be bug-related and should not be performed as part of a base migration. Try this only if all else fails.
At the site root, using the Add pull-down, add new versions of the Content Types Registry, MimetypesRegistry Tool, and PortalTransforms Tool (in that order). - At the site root, click portal_migration, and in the Upgrade tab, click the Upgrade button.
- After upgrading the site, click the View tab to test the main page.
- Click Site Setup, and then click Add/Remove Products.
- Under Installed Products, click the Migrate button to re-install any necessary existing products (in my case, this was CMFPlacefulWorkflow and Marshall).
- Download and un-archive any required products to /var/plone/zeocluster/Products
Make sure the product directories are complete, and that all contents have the proper owner ("plone"). - Re-start the cluster.
- In Site Setup on the Plone site, in Add/Remove Products, install the new products.
6.6. Upgrading from 3.x to 3.2
Plone 3.2 is the first fully egg-based Plone release.
Beginning with Plone 3.2, Plone will be available as a Python package and via installers. It will no longer be distributed as a tarball of old-fashioned Zope products. The change to standard Python packaging will improve dependency handling and make future installations easier. But, it will require some adjustments for those used to installing via a tarball of products. The 3.2.x installation will also require some slight changes in the buildout configuration file for those who have already been using buildout configuration management in the 3.x series.
Plone's installers take care of all this for you, but if you aren't using one of the installers you'll need to learn buildout — a Python configuration management tool we highly recommend — or use the Python package installer, easy_install, to install Plone. Both methods are discussed below.
Windows Updates
Users of past Windows installers should note: you should not try to simply install on top of your old Windows installation. That might have worked in the past, but it won't work with this upgrade. The move to a buildout-based installer has changed the layout of the subdirectories inside the installation. Do a new installation, get it working with all required products, then copy your old Data.fs file over the matching file in the new installation.
Buildout
All Plone's current installers use Buildout for configuration management. You should too, unless you're very experienced with Python packages. Buildout is the de facto standard for deploying Zope applications in a repeatable and easy way. The description of what will be installed is defined by a buildout configuration file, buildout.cfg.
If you're upgrading using buildout for the first time, take a look at General advice on updating from a non-buildout to buildout-based installation.
If you're updating an existing buildout, please note that the buildout files for 3.2.x look slightly different to those for 3.0 and 3.1 – they don't need a custom plone installation step as buildout can now handle it directly, here's an example of the relevant parts of buildout.cfg:
[buildout]
# parts: note that the plone part is no longer necessary.
parts =
zope2
instance
... Any other parts you've been using except "plone"
# find-links: only the new dist.plone.org URL is needed.
find-links =
http://dist.plone.org/
# New: this will pick up version settings for all the components.
# Modify the "3.2.x" to match the version you're seeking, e.g., 3.2.2.
extends = http://dist.plone.org/release/3.2.x/versions.cfg
versions = versions
# eggs: Plone is now specified in the egg section. All the
# dependencies are automatically handled.
eggs =
Plone
# zope part: Note the new fake-eggs settings. This is required
# for Zope dependencies to be resolved during buildout.
[zope2]
recipe = plone.recipe.zope2install
url = ${versions:zope2-url}
fake-zope-eggs = true
additional-fake-eggs =
ZConfig
ZODB3
pytz
# Everything else can usually be the same.
[instance]
recipe = plone.recipe.zope2instance
zope2-location = ${zope2:location}
...
# remove any reference to the plone part: e.g., ${plone:eggs} or ${plone:products}
If you have already modified your buildout.cfg file, for example to install new add-ons, remember to copy what you added to the eggs = and zcml = lines into the [instance] section.
If you've installed "old style" products you'll need to copy the productdistros section and add it to parts too.
After doing this, run bin/buildout -n, and your instance should update itself.
Old buildouts
There's been a recent change to the fake eggs mechanism that may cause a buildout error unless you delete the "develop-eggs" folder (or just its contents) from your buildout folder. It'll be recreated.
Custom buildout
To convert your existing custom buildout to Plone 3.2.x is very easy. The above example should be enough to make it clear what's needed, but in summary:
-
Remove the [plone] section and its entry from parts =. Also, remove all existing ${plone:...} references, including the ones inside the [zope2] and [instance] parts.
- Add the Plone egg to the eggs specification. Note that "Plone" is capitalized.
- Copy the extends = and versions = directives from above into your buildout, updating the version number to the target release.
- Modify the dist.plone.org line in find-links to match the version, as above.
- Add the two "fake-eggs" specifications above to the zope part specification.
easy_install and virtualenv
If you have special reasons for using a different or no python package manager you can install Plone via easy_install alone. If you choose this route we highly recommend that you use virtualenv to create an isolated Python instance before proceeding. Python libraries — and different versions of the same library — often conflict.
Plone is built on-top of the Zope application server and requires it to be installed for you to use Plone. You can install Plone directly into a python environment using the easy_install utility.
easy_install Plone
If you have multiple versions of Python installed you will need to use the easy_install that points to the same Python as your custom Zope install.
Version migration
No matter which technique you use to ugrade your Plone version, you'll need to use the portal_migrations tool in the Zope Management Interface to update your object database. This step is unchanged from past installations; see the general procedure.
A word on warnings
Whenever you run buildout and load new packages that have skin layers, you're likely to receive warnings indicating "'return' outside function." Ignore them, they're harmless. The warnings are produced when Python attempts to compile skin-layer Python scripts, which do indeed contain 'return' outside of function, but run in a context in which this is OK.6.7. Upgrading from 3.2 to 3.3.x
For most situations, this upgrade will be an easy one.
Upgrading from 3.2 to 3.3 is quick and easy. If you're upgrading from an earlier version, you should carefully read the upgrade instructions for the intervening versions. If you are upgrading to buildout for the first time, be sure to read General advice on updating from a non-buildout to buildout-based installation.
Upgrade Steps
Back up your entire installation. Stop the Zope/Plone process.
Edit your buildout.cfg file to use the 3.3 versions.cfg file.
extends = http://dist.plone.org/release/3.3.5/versions.cfg
- check http://plone.org/products/plone to see whether a more recent release is advised
- we have at least 3.3.5.
If you're using a buildout.cfg that reads versions.cfg from a file instead of a URL, you'll need to add this line and comment out the existing extends = versions.cfg line. Alternatively, you may download a new versions.cfg file from the URL above and point to that instead — if you prefer having the setup locally.
Make sure your [zope2] section (or equivalent using plone.recipe.zope2install) is pointing to the Zope version indicated in the previous versions.cfg:
[zope2]
recipe = plone.recipe.zope2install
url = ${versions:zope2-url}
Run buildout to download the updated packages and rebuild your startup commands. Change to the directory containing buildout.cfg and run:
bin/buildout
Windows users will use a backslash in place of the slash.
Restart Plone.
In the Zope Management Interface, visit portal_migration and use the upgrade button to update your database.
6.8. Upgrading Plone 3.x to 4.0
Upgrading your site and your products from Plone 3 to Plone 4.
6.8.1. Updating a custom Plone 3 buildout for Plone 4
The installers are the recommended way to install Plone 4, but if you have a custom buildout that you want to continue using, there are several changes you'll need to make.
If you have an existing buildout for a pre-4.0 Plone site, some updates are needed to make it work with Plone 4. These instructions assume that you are starting with a working buildout for a Plone 3.3.x site. If you're on an older version of Plone, see the appropriate section of this manual to upgrade it to Plone 3.3.x first.
Trying to update an existing buildout in place is not recommended. Work on a copy of your buildout configuration and site data until you are confident that the upgrade runs successfully.
If you need an example of a working Plone 4 buildout for comparison, look at the ones included in the installer for your platform, or generate one using ZopeSkel's plone3_buildout template. (Yes it has Plone 3 in its name, but as long as you have an up-to-date version of ZopeSkel and enter 4.0 when it prompts for the Plone version, it will generate a correct buildout.)
Common steps to update buildouts for Plone 4
- Plone 4 requires Python 2.6, whereas Plone 3 uses Python 2.4. Make sure that you start your buildout off on the right foot by running bootstrap.py using Python 2.6. (If you aren't sure how to get a Python 2.6 installation that works on your system, one option is to run the Plone installer, and then use the Python that it builds to run your custom buildout.) If you have set the executable variable in your ~/.buildout/default.cfg, remove it.
-
Make sure the [buildout] section has an extends setting which extends the official Plone versions.cfg file for the correct version of Plone. For example:
[buildout] extends = http://dist.plone.org/release/4.0/versions.cfg
If you are providing additional version pins, make sure that they are provided within the file that extends the Plone versions, or in a separate file that is extended after the Plone versions. Also make sure you don't inadvertently override any version pins from the core Plone set.
- Remove the part using the plone.recipe.zope2install recipe (this part is often called "zope2"). Zope 2 is now installed automatically as an egg dependency of the Plone egg, rather than via a special recipe. (Zope 2 also includes its own dependencies as eggs, so fake eggs are generally no longer required.) You will also need to remove any references to variables from the zope2 part from other parts (such as "${zope2:location}").
- Remove the zope2-location setting from the part using the plone.recipe.zope2instance recipe; it is no longer needed now that Zope 2 is an egg. Also update this part to specify the location of the BLOB storage directory that will be used by the instance:
blob-storage = ${buildout:directory}/var/blobstorageIf you will be running the instance as a ZEO client on the same machine as the ZEO server, you should configure both to use the same blobstorage directory, and set the shared-blob flag on each Zope instance:shared-blob = on
- If your buildout installs ZEO, make sure that you use the new plone.recipe.zeoserver recipe instead of plone.recipe.zope2zeoserver. The new recipe does not need a zope2-location setting, since ZODB is now installed as an egg. An example of a working ZEO part configuration:
[zeoserver] recipe = plone.recipe.zeoserver zeo-address = 8100
- If you are using the collective.recipe.filestorage recipe to set up filestorages for multiple ZODB mountpoints, you must make sure you are using the newest version of this recipe, and add the following line to its configuration so that blobstorage directories will be configured for each mountpoint:
blob-storage = var/blobstorage-%(fs_part_name)s
- If you are using the collective.recipe.supervisor recipe to install and configure supervisord to run your Plone processes, the correct way to start Zope in the foreground is now the "console" parameter to the instance script. The programs setting of this recipe must be updated to use that parameter instead of the old runzope script which is no longer generated by Zope. For example:
programs = 10 instance ${buildout:bin-directory}/instance [console] ${instance:location}
6.8.2. Updating add-on products for Plone 4
This is a list of the most common updates that need to be applied by product authors to ensure that their products work on Plone 4.
6.8.2.1. Detecting Plone 4
When Plone 3 and Plone 4 code branches differ you need to discriminate between Plone versions. You can do this using BBB imports.
Here is an example how to detect Plone 4 during imports. Then you can use PLONE_VERSION variable for making different code paths.
try:
# Plone 4 and higher
import plone.app.upgrade
PLONE_VERSION = 4
except ImportError:
PLONE_VERSION = 36.8.2.2. No more global definitions in templates
Lots of definitions that were available in templates in Plone 3.x are no longer there. You need to add the ones you really need yourself.
It is good practice in most cases to let the templates in your product use the main_template.pt of Plone. Until Plone 3.x this used to make a lot of variable definitions available directly in your template, as the main template pulled in definitions from the global_defines.pt template. This was handy, but the downside was that for every template lots of these variables were calculated but never used. The Plone developers decided that this was too expensive (when thinking in terms of processor time) and removed the global defines. This makes Plone faster, but it does ask for some changes in your product.
How do you know if your product needs changes? The theoretical approach would be to open all your templates in an editor and check if every variable that is used in a TALES expression (like tal:content or tal:define) has been defined earlier in that same template. Note that some variables are still globally available, the most important being context, view and template. A more practical approach is simply to try out your product in Plone 4, visit all pages that belong to your product and see if any errors occur. An error would look like this:
NameError: name 'templateId' is not defined
Look at this example changeset from CMFPlone itself to see the kind of changes that are needed.
How do you know what definition you should add to your template? The canonical place to look this up is the @@plone view from Plone 3 (not Plone 4). This is the file Products/CMFPlone/browser/ploneview.py, specifically the method _initializeData.
The most common variables that are now missing, including their definitions, are these:
<div
tal:define="template_id template/getId;
normalizeString nocall:context/@@plone/normalizeString;
toLocalizedTime nocall:context/@@plone/toLocalizedTime;
portal_properties context/portal_properties;
site_properties context/portal_properties/site_properties;
here_url context/@@plone_context_state/object_url;
portal context/@@plone_portal_state/portal;
isAnon context/@@plone_portal_state/anonymous;
member context/@@plone_portal_state/member;
actions python:context.portal_actions.listFilteredActionsFor(context);
mtool context/portal_membership;
wtool context/portal_workflow;
wf_state context/@@plone_context_state/workflow_state;
default_language context/@@plone_portal_state/default_language;
is_editable context/@@plone_context_state/is_editable;
isContextDefaultPage context/@@plone_context_state/is_default_page;
object_title context/@@plone_context_state/object_title;
putils context/plone_utils;
ztu modules/ZTUtils;
acl_users context/acl_users;
ifacetool context/portal_interface;
syntool context/portal_syndication;">
</div>
These changes are compatible with Plone 3.
Watch out for 'exists'!
A very sneaky thing can go wrong when you use the 'exists' keyword. Say you have a condition like this in your template:
tal:condition="python:exists('portal/beautiful.css')"
This condition is False when portal does not have the mentioned css file, but it also fails when portal is not defined! And you logically get no error message about this, but you just miss a piece of html or some css or javascript is not loaded because this condition is False. So you should go through your templates, search for the 'exists' keyword and check that everything that should be defined is actually defined.
6.8.2.3. The action icons tool (portal_actionicons) has been deprecated
Products providing icons for CMF actions should now register them using the 'icon_expr' setting on the action itself, rather than using the separate action icons tool.
In Plone 3, products could register icons associated with CMF actions using the action icons tool (portal_actionicons in the ZMI, actionicons.xml in GenericSetup profiles). In Plone 4 the action icons tool has been deprecated. Instead, actions in the actions tool and control panel tool can now have an associated icon expression which gives the URL of the icon.
For example, Kupu now registers the icon for its control panel using the following controlpanel.xml file in its GenericSetup profile:
<?xml version="1.0"?>
<object name="portal_controlpanel" meta_type="Plone Control Panel Tool">
<configlet title="Visual editor" action_id="kupu" appId="Kupu"
category="Plone" condition_expr=""
icon_expr="string:$portal_url/kupuimages/kupu_icon.gif"
url_expr="string:${portal_url}/kupu_library_tool/kupu_config"
visible="True">
<permission>Manage portal</permission>
</configlet>
</object>
The 'icon_expr' setting gives the URL for the icon associated with this configlet.
The 'icon_expr' setting may also be used with normal actions in the actions tool / actions.xml.
Registering icons with the action icons tool will still work in Plone 4, but it is deprecated and will no longer work in the next major release of Plone. You may remove actionicons.xml to avoid a deprecation warning, or leave it in place to maintain compatibility with Plone 3, depending on your needs.
6.8.2.4. No more Zope 2 interfaces
Versions of Zope 2 prior to Zope 2.12.0 supported two types of interfaces (the old Zope 2 implementation and the new Zope 3 implementation from zope.interface). Now only the latter remains.
In Plone 2.5 and Plone 3, Zope contained two different ways of declaring that a class implements a particular interface.
- Zope 2 style
-
from Interface import Interface class MyInterface(Interface): pass class MyClass(object): __implements__ = (MyInterface,) - Zope 3 style
-
from zope.interface import Interface class MyInterface(Interface): pass class MyClass(object): implements(MyInterface)
In Zope 2.12, only Zope 3 style interfaces are supported.
Code trying to define Zope 2 interfaces will raise the following exception:
ImportError: No module named Interface
Zope 2 style interfaces removed from ATContentTypes
In Plone 3, the Zope 2 style interfaces were defined in interfaces.py and the Zope 3 ones in the interface folder.
In Plone 4, the Zope 2 style interfaces have been removed and the Zope 3 ones moved to the interfaces submodule, to follow naming conventions. However, a link to these Zope 3 interfaces has been left in interface.py, so the following example code will work in both Plone 3 and 4:
from Products.ATContentTypes.interface import IATFolder
Trying to use implements() with Zope 2 style interfaces will fail.
6.8.2.5. Miscellaneous import changes
A number of imports have been moved to new locations. In addition, a number of previously deprecated methods have been removed.
Moved
P = Abbreviation for "Products".
| Old location | New location |
|---|---|
| P.ATContentTypes.content.folder.ATFolder |
plone.app.folder.folder.ATFolder |
| P.ATContentTypes.content.folder.ATFolderSchema | plone.app.folder.folder.ATFolderSchema |
| P.CMFPlone.browser.navtree.\ SitemapNavtreeStrategy.icon |
P.CMFPlone.browser.navtree.SitemapNavtreeStrategy.item_icon |
| P.CMFPlone.browser.plone |
P.CMFPlone.browser.ploneview |
| P.CMFPlone.browser.ploneview.cache_decorator |
plone.memoize.instance.memoize |
| P.CMFPlone.browser.ploneview.Plone.isRightToLeft |
@@plone_portal_state/is_rtl |
| P.CMFPlone.browser.ploneview.\ Plone.keyFilteredActions |
@@plone_context_state/keyed_actions |
| P.CMFPlone.browser.portlets |
plone.app.portlets.portlets |
| P.CMFPlone.interfaces.OrderedContainer.\ IOrderedContainer |
OFS.interfaces.IOrderedContainer |
| P.CMFPlone.utils.BrowserView |
P.Five.BrowserView |
| P.CMFPlone.utils.getGlobalTranslationService |
P.PageTemplates.GlobalTranslationService.getGlobalTranslationService |
| P.CMFPlone.utils.scale_image P.CMFPlone.utils.utranslate P.PageTemplates.GlobalTranslationService.\ getGlobalTranslationService |
P.PlonePAS.utils.scale_image zope.i18n.translate zope.i18n |
| P.CMFPlone.utils.ulocalized_time |
P.CMFPlone.i18nl10n.ulocalized_time |
| zope.app.cache.interfaces.ram.IRAMCache |
zope.ramcache.interfaces.ram.IRAMCache |
| P.ATReferenceBrowserWidget.\ ATReferenceBrowserWidget.ReferenceBrowserWidget |
archetypes.referencebrowserwidget.ReferenceBrowserWidget |
Removed
| Products.CMFPlone.CatalogTool.registerIndexableAttribute – see the plone.indexer package instead. |
| Products.CMFPlone.PloneTool.setDefaultSkin |
| Products.CMFPlone.PloneTool.setCurrentSkin |
| Products.CMFPlone.PortalContent |
| Products.CMFPlone.browser.ploneview.IndexIterator, Products.CMFPlone.utils.IndexIterator |
| the Favorite content type |
| use_folder_tabs from site_properties |
| The 'actions' method of @@plone_context_state now takes a single parameter which is the action category that should be retrieved. This should be used instead of the 'keyed_actions' method which has been removed. |
Items removed from the plone_deprecated skin layer:
|
6.8.2.6. AdvancedQuery has been removed from Plone core
AdvancedQuery is no longer included with Plone 4, but you may declare it as a dependency for add-on products.
Plone 4 no longer includes AdvancedQuery. In Plone 3, it was used only by wicked, and the Plone 4 version of wicked no longer requires AdvancedQuery. AdvancedQuery was seen by the Plone 4.0 Framework Team as a risky dependency because it is maintained in a private repository rather than in the Plone core or Collective repositories.
If your add-on product or custom code depends on AdvancedQuery, you will need to explicitly require it now. You can do this by including dependency in your add-on product's setup.py
install_requires=[
'setuptools',
'Products.AdvancedQuery',
6.8.2.7. Validators
Validators no longer function with old style zope 2 interfaces but need new zope 3 style interfaces.
Error you may get when starting your zope instance:
Products.validation.exceptions.FalseValidatorError: <Products.PloneSoftwareCenter.validators.ProjectIdValidator instance at 0xa92082c>
This means that the specified validator is using old interfaces and is not working anymore. You need to remove this line:
__implements__= (IValidator,)
(IValidator might be called ivalidator in all lowercase, at least in this specific example) and replace it with this:
implements(IValidator)
Example changesets:
- DataGridField (only part of the changeset applies)
- PloneSoftwareCenter
If you now use this code on Plone 3, this will fail:
TypeError: Error when calling the metaclass bases iteration over non-sequence
So if you want to avoid that and be compatible with Plone 3 and 4 at the same time, you can conditionally use either of the two lines, like in this changeset.
6.8.2.8. Manual calls to translate
When you directly call the 'translate' method in your code, there are some changes.
If you have any of these imports, you cannot use them anymore:
Products.CMFPlone.utils.utranslate Products.PageTemplates.GlobalTranslationService.getGlobalTranslationService
Instead you need to use zope.i18n.translate directly. See this example changeset from Poi.
The tricky thing here is that the order of the arguments has changed so you probably need some more changes. The old call signature was this:
utranslate(domain, msgid, mapping=None, context=None,
target_language=None, default=None)
And the new is this:
translate(msgid, domain=None, mapping=None, context=None,
target_language=None, default=None)
So:
- msgid is now the first instead of the second call
- domain is now optional
6.8.2.9. Use plone.app.blob-based BLOB storage
Plone 4 ships with a new type of storage specially designed for large binary objects, as images or other files. Here you can learn how to use this feature for new content types and how to and prepare your already existing content types to use the new BLOB storage.
Using plone.app.blob for new content types
Just use plone.app.field.BlobField or plone.app.field.ImageField instead of atapi.FileField or atapi.ImageField (respectively) in your schema:
from Products.Archetypes import atapi
from plone.app.blob.field import BlobField, ImageField
schema = atapi.Schema((
BlobField('afile',
widget=atapi.FileWidget(label='A file',
description='Some file'),
required=True,
),
ImageField('animage',
widget=atapi.ImageWidget(label='An image',
description='Some image'),
),
))
Check the Archetypes Fields Reference for details.
Preparing already existing content types
In order to prepare your own content types to use blobs and provide migration facilities to your users once plone.app.blob is available, you need to perform the following steps. Check example.blobattype for example code.
Use a schema extender to replace the FileField(s) of your content type with BlobField(s). For detailed information on how to do so please look into the archetypes.schemaextender documentation. In essence this breaks down to:
-
Creating an extension field:
class ExtensionBlobField(ExtensionField, BlobField):
""" derivative of blobfield for extending schemas """ -
Extending your content type to use the blob fields. So for instance if your content type ExampleATType has a field named file you will need to register a schema extender like the following:
class ExampleATTypeExtender(object):
adapts(IExampleATType)
implements(ISchemaExtender)
fields = [
ExtensionBlobField('file',
widget=atapi.FileWidget(
label=_(u"File"),
description=_(u"Some file"),
),
required=True,
validators=('isNonEmptyFile'),
),
]
def __init__(self, context):
self.context = context
def getFields(self):
return self.fieldsIf you want to be able to still use your content type without plone.app.blob in sites that have not yet installed support for blobs, you will find it convenient to register the adapter conditionally like so:
<adapter
zcml:condition="installed plone.app.blob"
factory=".extender.ExampleATTypeExtender" />This way, if plone.app.blob is not installed your original FileField(s) will be used.
-
Provide a migration function for your content. The easiest way to do so is to use the helper method from plone.app.blob. Given a portal type name it will automatically find all blob-aware fields as defined by the schema extender above and perform migrations for those. It is as simple as:
from plone.app.blob.migrations import migrate
def migrateExampleATTypes(context):
return migrate(context, 'ExampleATType')You can now call migrateExampleATTypes from a view or a script to migrate existing content items of the specified type. If you need more control, you can write your own migrator. Please refer to example.blobattype for more details on how to do this.
6.8.2.10. Add views for content types
In Plone 4, every Factory Type Information object in portal_types will have an additional, optional property which can be set to a TALES expression to provide the URL of a view that will be shown when the user chooses to add an object of this particular type from the "Add" menu in Plone.
This property has the title Add view URL
(expression) and the internal id add_view_expr.
For example, if you have a custom add form called
@@add-my-content, you could set this expression to
string:${folder_url}/@@add-my-content. (Note that the view in this
case needs to be registered for the folder type, not for the type being
created.)
If this property is not set, Plone will fall back on the
createObject script as before, which in turn will create the object
or invoke the portal_factory tool. This is likely to be the correct
behaviour for most Archetypes-based content objects.
In Plone 3, it was possible to have an add view be invoked by
registering a view for the IAdding view (aka the + view) that had
the same name as the factory property specified in the Factory Type
Information. For example, a type with a factory of my.type could be
accompanied by a view with the name 'my.type' registered for the
IAdding interface. This would be found and preferred over the
createObject script, and was sometimes used with non-Archetypes
content.
In Plone 4, this association needs to be made explicit. (This is
mainly for performance reasons.) To use such an add view, you need to
set the add_view_expr property to invoke it, e.g.
string:${folder_url}/+/my.type.
Finally, note that the IAdding (+) view is falling out of favour. It
will continue to work indefinitely, but most people these days prefer
to register a simple view (e.g. @@add-my-content) for the folder type
(e.g. the IFolderish interface from Products.CMFCore.interfaces)
which constructs and adds the content in reaction to a valid form
submission. This is because the "view-on-a-view" concept used by
IAdding can be confusing and requires special handling in certain
places (e.g. some vocabulary factories) to deal with the fact that
view.context is another view, not a content object. The add form base
classes in zope.formlib still use the IAdding view, but z3c.form
comes with an add form base class that acts as a simple view.
6.8.2.11. 'MailHost.secureSend' is now deprecated; use 'send' instead
The SecureMailHost product is no longer a part of Plone in 4.0. As a result, the 'secureSend' method which was generally used to send mail is now deprecated. The default 'send' method of MailHost should be used instead.
In Plone 2.1 - 3.x the standard method for sending mail looked like this:
mh = getToolByName(context, 'MailHost')
mh.secureSend(message, mto, mfrom, subject=None,
mcc=None, mbcc=None, subtype=None,
charset=None, **kwargs)
Where the message parameter is either text with no headers or an email.Message.Message object, the mto, mfrom, mcc and mbcc parameters are lists of email addresses, subject is content of the email subject header, subtype is used to provide the message mime sub-type, charset is used for message and header encoding, and the kwargs are used to provide additional headers.
In Plone 4.x, this method is deprecated and the standard send method of the MailHost should be used instead. The following is an example of using send:
mh = getToolByName(context, 'MailHost')
mh.send(messageText, mto=None, mfrom=None,
subject=None, encode=None,
immediate=False, charset='utf8', msg_type=None)
Here, messageText is the message with or without headers or an email.Message.Message object, mto and mfrom are strings containing the to and from addresses, subject is the content of the email subject header, encode is used to specify the message payload encoding (and should almost never be used), immediate is used to override the default MailHost queuing behavior, and charset is used for message and header character encoding (in Plone you should generally pass 'utf8' as the value for charset unless you have a specific reason not to). If you need to set custom headers they will need to be set in the messageText itself.
Message Type
Instead of passing the MIME subtype as the subtype parameter to set the message content type, you pass the full MIME type as msg_type. So instead of subtype='plain' you would use msg_type='text/plain'.
Custom Headers
The secureSend method had provided the ability to set some specific headers, and to set custom headers as well. Unfortunately, send does not allow doing this directly; fortunately it is pretty simple to construct a message with custom headers to pass to send. Below is an example that assumes you have the MailHost object and have already defined message_body, mto, mfrom and subject:
from email import message_from_string
from email.Header import Header
my_message = message_from_string(message_body.encode('utf-8'))
my_message.set_charset('utf-8')
my_message['CC']= Header('someone@example.com')
my_message['BCC']= Header('secret@example.com')
my_message['X-Custom'] = Header(u'Some Custom Parameter', 'utf-8')
mailhost.send(my_message, mto, mfrom, subject)
Delayed Sending
By default send waits to send messages until the end of the request transaction. This ensures that if a conflict error occurs and the transaction is retried, multiple emails will not be sent (which is what happens with secureSend and earlier versions of send). Unfortunately, this means that unless you explicitly request immediate=True when using send, you will not be able to catch any errors which might happen during sending, as they won't occur until the end of the transaction.
If you want to handle email errors to prevent them from aborting an otherwise successful transaction, you need to set immediate=True and enclose the send call in a try/except block. Alternatively, you can go the the MailHost configuration screen in the ZMI and enable SMTP Queuing. This will ensure the mail sending happens completely outside of the transaction, providing more reliability and increased performance while still avoiding transaction retry issues. Using the new MailHost queueing feature is highly recommended for production sites.
Writing Tests
Plone includes some helpers for writing tests that need to use email in the Products.CMFPlone.tests.utils and Products.CMFPlone.tests.test_mails modules. These include a MockMailHost and a MockMailHostTestCase that replaces the MailHost in the test Plone site with a MockMailHost object. For products that make use of Plone's MockMailHost in their own tests, there are a few more changes that need to be made.
The messages property of the mail host no longer includes the an email.Message object, but instead contains a string representation of message. This means that in order to test the message object you can either work directly with the message string, or convert it into a email message object using the message_from_string function used in the last example.
Summary
In most cases, all you need to do to use send instead of secureSend is convert your mto and mfrom parameters from lists to comma separated strings, and add any CC, BCC, or other headers directly to the messageText instead of passing them as parameters. If you are using secureSend to add custom headers or make other adjustments to the message, the changes are a little more involved, but still straightforward. Additionally, if you are using Plone's MockMailHost in your tests you will need to update your tests to work with the message string rather than an email.Message object.
6.8.2.12. Portlets Generic Setup syntax changes
The syntax for limiting portlets to a certain type of manager has changed.
The original format for limiting a portlet to a certain type of manager was:
<portlet addview="portlets.BBB"
title="Foo"
description="Foo"
for="plone.app.portlets.interfaces.IColumn" />
but this form was deprecated in Plone 3.1 to allow multiple values in the for field. In Plone 4 the required form is:
<portlet title="Foo"
addview="portlets.New"
description="Foo">
<for interface="plone.app.portlets.interfaces.IColumn" />
<for interface="plone.app.portlets.interfaces.IDashboard" />
</portlet>
6.8.2.13. Updating Plone 3 themes for Plone 4
Plone 3 themes may require a few modifications in order to work in Plone 4, depending on how much template customization was done.
Plone 4's Built-in Themes
Plone 3 shipped with two skins, Plone Default and NuPlone.
Plone 4 includes three skins:
- Sunburst Theme
- A new, modern skin, packaged in the plonetheme.sunburst egg. Sunburst is the default skin for newly created sites.
- Plone Classic Theme
- The old default skin that was called Plone Default in Plone 3. It is now packaged in the plonetheme.classic egg.
- Plone Default (or "Unstyled")
- The "Plone Default" skin is now just a barebones interface with no CSS styling, intended for use with post-processing theming engines such as xdv or deliverance.
Plone 4 no longer ships with NuPlone, but it is still available as an add-on.
Upgrading a Plone 3 site with an existing theme
If you upgrade a site from an older version of Plone to Plone 4, the automatic upgrade will try to do something reasonable with the theme.
If you have installed and selected a custom theme, almost no changes will be made. The exception is that the 'plone_styles' skin layer will be replaced by the 'classic_styles' layer, since the name of this layer used by the Plone Classic Theme has been renamed. You may need to take additional steps to update the theme to work properly in Plone 4, as described below.
If your skin was set to "Plone Default" with the default set of skin layers, your skin will be set to "Plone Classic Theme," which should look the same.
If your skin was set to "Plone Default" but you have customized it by changing the skin layers used (or installing add-ons which add additional skin layers), then these skin selections will be copied to a new skin called "Old Plone 3 Custom Theme," which will be made active. The viewlet configuration will also be preserved.
Updating a theme to work in Plone 4
There are several updates you may need to make to a custom theme to make sure that it continues to work in Plone 4.
Updates to main_template.pt
If your theme has a custom version of main_template.pt, it will need to be updated. The best way to do this is probably to compare the custom main_template to the one that shipped with Plone 3, and then start over with a fresh copy of main_template from Plone 4 and re-apply the same modifications that had been made. In particular, watch for the following changes in main_template:
- The defines on the html tag have been modified.
- Some new defines have been added to the body tag.
- main_template now includes the standard viewlet managers used within the main content area, and defines a new slot called "content-core" where the actual content body goes.
Updates to template variables
Templates that have been overridden must be reviewed to make sure new changes to the original templates are included. Also, check to make sure they are not using global template variables that are no longer available.
Update the "based-on" declarations
If your theme is installed via a GenericSetup profile, then you probably have a profiles/default/skins.xml file which declares a "skin-path" consisting of various layers. The skin path declaration may say based-on="Plone Default". If so, update it to say based-on="Plone Classic Theme" so that it will continue to use the same set of layers as a basis that it did in Plone 3. If the "plone_styles" layer is referenced by name, change it to "classic_styles".
Similarly, you may have a profiles/default/viewlets.xml file which customizes the viewlets used in your theme. If any of the "order" or "hidden" manager directives in this file say based-on="Plone Default", update them to say based-on="Plone Classic Theme" instead.
Update the theme-specific interface
Your theme may define a Zope 3 interface called IThemeSpecific in browser/interfaces.py. If so, update it so that it extends the theme interface from the Plone Classic Theme:
from plonetheme.classic.browser.interfaces import IThemeSpecific as IClassicTheme
class IThemeSpecific(IClassicTheme):
"""theme-specific layer"""
This will ensure that your theme continues to have available the viewlets that are registered for the Plone Classic Theme only, as there are several which are slightly customized compared to the default viewlets of Plone 4 used by the Sunburst theme.
6.8.2.14. New users and groups functionality
Some pages have been renamed and moved, registration made flexible, and nested groups enabled by default.
join_form moved and renamed
In Plone 3, the login form was living in the portal_skins/plone_login skin layer of the Plone (Products.CMFPlone) package. This form has been moved to a Zope 3 view named @@register in the plone.app.users package.
This means that you'll have to adapt any customizations made to the join_form template to use the new @@register view.
Added @@new-user form
This is the form that site administrators, or any other user with the Manage users permission, can use to add new users, bypassing the Enable self-registration and Let users select their own passwords settings, that only affect the public @@register form.
User registration fields made flexible
The new join and user-addding forms let you to select the groups to which the user will be assigned once created. You can customize which fields do you want to be shown in this form from the Site Setup → Users and Groups → Member registration dialog. You can also modify the list programatically and add new fields as described in collective.examples.userdata.
Nested groups enabled by default
When viewing a group's membership page, you can add groups as well as users as members. This way, members of the nested group inherit all roles and permissions assigned to the parent group. For example, the "Biology Department" and "Chemistry Department" groups as well as the college's Dean may belong to the "Science" group. If "Science" is given view rights over the college's intranet folder, the Dean, and anyone belonging to the Biology or Chemisty groups would gain view access to that folder.
If you want to disable this behavior, deactivate the recursive_groups plugin at plone_site_root/acl_users/plugins/Groups Plugins.
6.8.2.15. Make sure your templates are valid XML
It's always been "best practice" to make sure your templates validate, even though it's not required. With Plone 4, there are even more benefits to doing so.
It's long been considered "best practice" to make sure that all of the templates in your custom products validate as valid XML. But, since web browsers are so forgiving of sloppy markup, it has also been the case that there have been few strong incentives to make sure your XML is perfectly valid. Until now.
By using Chameleon, a drop-in replacement for Zope's ZPT template rendering engine, a Plone 4 site can immediate experience 25-50% improvements in performance. However, Chameleon absolutely requires that all page templates be valid XML.
Plone 4 does not include Chameleon, although it can be added as an add-on product. Current plans call for Plone 5 to use Chameleon by default, and it may start shipping (disabled) with a future release in the Plone 4.x series (as of this writing, possibly Plone 4.2). Bottom line: as you're updating your add-on products for Plone 4, now is the perfect time to double-check your templates to make sure they're well-formed XML.
The simplest way to validate your templates is probably to use xmllint. You can also use the W3C validator, either online or on your Mac OS X system.
6.8.2.16. document_byline and some other macros are now viewlets
Some content relatd TAL macros have been removed and replaced with viewlets.
This change concerns theme and add-on product authors who have custom content templates.
If your template had a byline macro, which shows the author name, before like
<div metal:use-macro="context/document_byline/macros/byline"></div>
it does not work anymore (you will receive AttributeError: document_byline).
Byline is now rendered by a viewlet plone.belowcontenttitle.documentbyline (from package plone.app.layout.viewlets) which is defined in a viewlet manager IBelowContentTitle. You need to change this to your content templates.
<div tal:replace="structure provider:plone.belowcontenttitle" />
The same goes for document actions. Old:
<div metal:use-macro="context/document_actions/macros/document_actions"></div>
New:
<div tal:replace="structure provider:plone.documentactions" />
For templates and macros checklist, please see this.
6.8.2.17. No longer bin/instance test - use zc.recipe.testrunner
Zope 2 start-up script no longer supports running tests. You need to use zc.recipe.testrunner for this purpose.
Add to your builout.cfg:
parts =
...
test
[test]
recipe = zc.recipe.testrunner
defaults = ['--auto-color', '--auto-progress']
eggs =
${instance:eggs}
Rerun buildout.Then you can run tests:
bin/test -s your.packagename
See z3c.recipe.testrunner page for more information.
Changes in PloneTestCase setup
If you previously set up a PloneTestCase as explained in the developer manualyou might need to change the initialization of Zope2 products:
from Products.Five import zcml
from Testing import ZopeTestCase as ztc
from Products.PloneTestCase import PloneTestCase as ptc
from Products.PloneTestCase.layer import onsetup
@onsetup
def setup_product():
import my.types
zcml.load_config('configure.zcml', my.types)
# We need to tell the testing framework that these products
# should be available. This can't happen until after we have loaded
# the ZCML.
ztc.installProduct('TextIndexNG3')
ztc.installPackage('my.types')
setup_product()
ptc.setupPloneSite(products=['my.types'])
ztc.installProduct('TextIndexNG3') needs to be moved out of the deferred method setup_product so it's initialized properly:
@onsetup
def setup_product():
import my.types
zcml.load_config('configure.zcml', my.types)
# We need to tell the testing framework that these products
# should be available. This can't happen until after we have loaded
# the ZCML.
ztc.installPackage('my.types')
#initialize products outside of the deferred (@onsetup) method, otherwise it's too late
ztc.installProduct('TextIndexNG3')
setup_product()
ptc.setupPloneSite(products=['my.types'])
see the blogpost describing this issue in more details
6.8.2.18. Vocabulary Directive now replaced by Utilities
Vocabulary factories should be registered using utilities
Previously a named vocabulary would be registered in this manner:
- Zope 2 style
-
<vocabulary name="collective.exampleapp.Subscribers" factory=".vocabularies.Subscribers" />
- Zope 3 style
-
<utility name="collective.exampleapp.Subscribers" component=".vocabularies.Subscribers" provides="zope.app.schema.vocabulary.IVocabularyFactory" />See another example of using a utility in the community documentation. - Or register your vocabularies using a grok utility
- Read more about how vocabularies are handled the grok way in the dexterity developer manual
- Code that attempts to use the Zope 2 style vocabulary directive will throw a configuration error
-
ConfigurationError: ('Unknown directive', u'http://namespaces.zope.org/zope', u'vocabulary')
6.8.2.19. Folder implementation changes
Large Folder and Folder content types have been unified in Plone 4. This may impact your add-on product code.
Plone 4 unifies two different folder implementations (Folder and Large Folder) to one implementation. There are internal changes to ATFolder base classes (Archetypes folder implementation). This change simplifies code, API and makes folders scale better.
plone.app.folder is the new package providing the folder code. plone.app.folder provides a migration view which is run during Plone 4 upgrade for all ATFolder based content.
6.8.2.20. Empty /Control_Panel/Products using Plone 4
In Plone 4 Zope Management Interface's Products section has been turned off.
In ZMI, /Control_Panel/Products shows no products, and says "There are currently no items in Product Management"
It was turned off in Plone 4.
6.8.3. Deprecated Templates Checklist
A number of the templates in plone_deprecated have now been removed completely. If your theme or product has customized these, you will need to replace them with the corresponding viewlet or portlet.
| Deprecated template |
Replacement in Plone 4 |
Type |
| colophon.pt |
plone.colophon |
viewlet |
| document_actions.pt |
plone.documentactions |
viewletmanager |
| document_byline.pt |
plone.belowcontenttitle.documentbyline |
viewlet |
| footer.pt |
plone.footer |
viewlet |
| global_contentviews.pt |
plone.contentviews |
viewlet |
| global_pathbar.pt |
plone.path_bar |
viewlet |
| global_personalbar.pt |
plone.personal_bar |
viewlet |
| global_searchbox.pt |
plone.searchbox |
viewlet |
| global_sections.pt |
plone.global_sections |
viewlet |
| portlet_calendar.pt |
portlets.Calendar |
portlet |
| portlet_events.pt |
portlets.Events |
portlet |
| portlet_languages.pt |
portlets.Language |
portlet |
| portlet_login.pt |
portlets.Login |
portlet |
| portlet_navigation.pt |
portlets.Navigation |
portlet |
| portlet_news.pt |
portlets.News |
portlet |
| portlet_recent.pt |
portlets.Recent |
portlet |
| portlet_related.pt |
plone.belowcontentbody.relateditems |
viewlet |
| portlet_review.pt |
portlets.Review |
portlet |
| review_history.pt |
plone.belowcontentbody.contenthistory |
viewlet |
For more info about how the viewlet architecture replaced METAL macros check the Customizing the viewlets in main_template tutorial.
For an overview of the Plone portlets infrastucture, see the Portlets section of the Developer Manual.
6.8.4. Email address-based login
You can now allow users to use their email address as login name. This feature can be switched on in the Security settings control panel. The effect is that on the registration form no field is shown for the user name. On the login form the user is now asked to fill in an email address. A list of questions and answers about this new feature, including use and migration, is presented here.
When this feature is enabled, can I log in with either my username and my email address or only my email address?
After you enable this feature, new users can only login with their email address.
For existing accounts that were created before enabling this feature, it is slightly different. They need to login once with their username, edit their preferences and save that form. That will update their account info. Now they can logout and then login with their email address.
To prevent this strange situation, as Manager you can add @@migrate-to-emaillogin to the url of your website. In that form you can set the email address as the login name for all existing users. Now all existing users can also login with their email address.
Is this feature enabled by default in new Plone 4 sites? Will it get activated if I migrate to P4 from a previous version?
No, it is not enabled by default. No, it will not get activated during migration.
How can I activate/deactivate this feature? Are there any possible issues during activation/deactivation I should know about?
In the Site Setup go to the Security Panel. Check or uncheck the Use email address as login name option and save the form.
Activating this on a website that already has users may be confusing for those users. When logging in they will be asked for their email address, but these existing users should actually still login with the login name they have chosen. They should edit their personal preferences once and save the form and then they can login with their email address.
Also, activating this may give unexpected results when there are two user accounts that have the same email address. At least they will not be able to use their email address for logging in, so they should still use their original login name.
The solution for those two situations, is the @@migrate-to-emaillogin form. Add that to the url of your website. In that form, you can check if any existing users have the same email address. Also, you can set the email address as the login name for all existing users. Now all existing users can immediately login with their email address, without having to edit their preferences.
When you no longer want users to login with their email address, you can use this form to reset their login name to their user id. Note that this has no real effect for users that never had a separate user id to begin with; their email address will remain their user id.
What happens when I change my email address?
When you change your email address, you can only login with your new address, not your old. Also, for safety no-one can register an account with the email address you initially used.
6.8.5. Upgrading Caching Products
Plone 3's primary caching add-on product, CacheFu (aka CacheSetup) is not compatible with Plone 4. It has been replaced by plone.app.caching, a more modern and powerful caching subsystem.
Many production Plone sites use the add-on CacheFu (aka CacheSetup) to boost site performance. This is a widely recognized "best practice." However, CacheFu is not compatible with Plone 4.
Do not despair: the Plone community has created a new, simpler and more powerful replacement for CacheFu called plone.app.caching, which is Plone 4 compatible.
If your Plone 3 site currently includes CacheFu/CacheSetup, you should:
- Uninstall CacheFu from your Plone 3 site before upgrading it to Plone 4. (If, after migration, your site triggers "AttributeError: getHTTPCachingHeaders" on file system resources, try reconfiguring CacheFu to not use a proxy and turn it off before uninstalling it.)
- After upgrading to Plone 3, install plone.app.caching and configure it appropriately. If you have highly customized rules for CacheFu, you may need to recreate these for plone.app.caching.
Do not attempt to upgrade a Plone 3 site to Plone 4 without uninstalling CacheFu first. Your migrated site will fail to start up, and you won't be able to effectively remove CacheFu at this point.
However, if you should already find yourself in this situation before reading this document, there does exist a Plone-4 compatible branch of CacheFu. This branch is unmaintained and not recommended for production use under Plone 4, but it works well enough to allow you to boot your instance and remove CacheFu.
6.9. Upgrading Plone 4.0 to 4.1
Upgrading your site and your products from Plone 4.0 to Plone 4.1.
6.9.1. Updating add-on products for Plone 4.1
This is a list of the most common updates that need to be applied by product authors to ensure that their products work on Plone 4.1.
6.9.1.1. Changing dependencies from Plone to Products.CMFPlone, updating permissions and aliases
Plone 4.1 separates the Products.CMFPlone package from the Plone egg to give integrators the option of building Plone sites with a cut down feature set.
Updating your setup.py
In your package's setup.py where you currently have:
install_requires=[
'setuptools',
'Plone',
],
Instead you should use:
install_requires=[
'setuptools',
'Products.CMFPlone',
],
You should also list the other packages you depend on, e.g. Products.Archetypes or plone.app.portlets.
Updating Permissions
If you are protecting any templates, pages, etc... in zcml with CMF core permissions (anything in the cmf namespace, e.g. cmf.ModifyPortalContent), you must add the following to configure.zcml:
<include package="Products.CMFCore" />
Most importantly this loads the permissions.zcml, if it is available. The above statement is the easiest and will work in all Plone versions; previously a more fancy statement with a condition was advocated, which we will give here for good measure:
<include package="Products.CMFCore" file="permissions.zcml"
xmlns:zcml="http://namespaces.zope.org/zcml"
zcml:condition="have plone-41" />
Updating Aliases
Some old import aliases may no longer work. Please update:
- from Products.CMFPlone import Batch -> from Products.CMFPlone.PloneBatch import Batch
- from zope.app.interface import queryType -> from zope.app.content import queryType
- from Products.Five.formlib import formbase -> from five.formlib import formbase (this counts for a lot of formlib changes - most things are now imported from five.formlib.formbase)
Maintaining compatibility with Plone 4.0 and 3.3
Version 4.0 of Products.CMFPlone is a forward compatibility shim (an empty egg depending on the Plone package) to enable Plone extension packages depending on Products.CMFPlone to continue working with Plone 4.0 or 3.3.
6.9.1.2. Use Generic Setup for defining versioning policies
From Plone 4.1 on, versioning policies for custom types can be configured using Generic Setup (repositorytool.xml)
If you activated versioning for your custom content types you most likely followed one of these How-Tos:
Both basically recommend to set the versioning policies CMFEditions is using in a custom setuphandler:
from Products.CMFEditions.setuphandlers import DEFAULT_POLICIES portal_repository = getToolByName(portal, 'portal_repository') versionable_types = list(portal_repository.getVersionableContentTypes()) for type_id in ['MyType', 'AnotherType']: if type_id not in versionable_types: versionable_types.append(type_id) # Add default versioning policies to the versioned type for policy_id in DEFAULT_POLICIES: portal_repository.addPolicyForContentType(type_id, policy_id) portal_repository.setVersionableContentTypes(versionable_types)
when migrating to plone4.1 you'll get the following error:
ImportError: cannot import name DEFAULT_POLICIES
To make your Product compatible with Plone4.1 you can remove the code for setting versionableContenttypes above and simply add a file named repositorytool.xml to your package's Generic Setup profile and you're done:
<?xml version="1.0"?>
<repositorytool>
<policymap>
<type name="MyType">
<policy name="at_edit_autoversion"/>
<policy name="version_on_revert"/>
</type>
<type name="AnotherType">
<policy name="at_edit_autoversion"/>
<policy name="version_on_revert"/>
</type>
</policymap>
</repositorytool>
If you need to be backward compatible you can add repositorytool.xml (which will be used in plone >= 4.1) and add a condition to your setupandler. eg:
try:
from Products.CMFEditions.setuphandlers import DEFAULT_POLICIES
# we're on plone < 4.1, configure versionable types manually
setVersionedTypes(portal)
except ImportError:
# repositorytool.xml will be used
pass
6.10. Upgrading Plone 4.1 to 4.2
6.10.1. Upgrades to zc.buildout
Re-running bootstrap.py may cause some
Note: There is a minutely small chance this actually affects you.
By default, bootstrap.py now uses zc.buildout version 1.5.2 instead of 1.4.4. 1.5.2 no longer references your global python site packages and you may need to upgrade any custom products to specifically pull those package into the local build.
If you are having buildout ills, please check the buildout troubleshooting guide to try and fix it.
6.10.2. Search Templates
Search has been dramatically improved in 4.2, but that means that any customizations you may have made could be gone or just plain won't work. If you previously customized search in your custom folder or anywhere in skins, note that your shizzle won't work anymore.
You can do two things (I think - I'm sure there is a better way but if anyone has an idea paste it here!). You can keep your search form and all of it's logic in template mumble jumble. That info is below but why would you want to do that? I recommend customizing the shiny NEW search template to have your changes once again since it's just so gosh darn pretty.
To upgrade your sites search to be more like what you want (and flex your brain), copy plone.app.search/plone/app/search/search.pt into your templates folder in your product. Something like my.site/my/site/browser/templates/mysite_search.pt. I recommend using another name besides search.pt for sanity. Then override the search view to use the new template in your configure.zcml (likely in browser):
<browser:page name="search" class="plone.app.search.browser.Search" permission="zope2.View" for="Products.CMFPlone.interfaces.IPloneSiteRoot" layer="my.site.interfaces.IMySiteLayer" template="templates/mysite_search.pt"/>
Restart and make sure that's all working. Then update that search template to have all your changes that you had in the old template.
If you aren't convinced by the boat load of pretty that is the new search form, don't copy or paste anything and just omit the class= line in the code above. You can paste your old template as is. I'll sigh for you... *sigh*. It will look something like
<browser:page name="search" permission="zope2.View" for="Products.CMFPlone.interfaces.IPloneSiteRoot" layer="my.site.interfaces.IMySiteLayer" template="templates/search.pt"/>
6.10.3. Upgrading to new collections
Upgrading
When upgrading your Plone site, the old collections will still be available to you only they're now labeled "Collection (old-style)." Old collections will NOT be migrated to new-style collections.
Enabling old-style collections
If you're starting a new Plone site from scratch, the old collections will not be enabled by default and you may still want to use them on your site--especially if you're running add-ons that still depend on the old-style collections.
To manual enable old-style collections, follow these steps:
- Visit the ZMI(or append /manage onto the url of your plone site)
- Click "portal_types"
- Click "Topic (Collection (old-style))"
- Check the "Implicitly addable?"
- Click the "Save" button
Developing for old and new collections
New style collections still implement the queryCatalog method which results the results from the catalog query so most likely the only thing you'll need to change is interface registrations and references to portal_type.
I have just updated collective.plonetruegallery for the new collections so I'll share some tips on integrating.
Conditional ZCML
In order to be backward compatible, you should use conditional zcml for any registrations or code that needs to be loaded. The collective docs has a good section on how to do this.
A simple example in practice is:
<browser:page zcml:condition="installed plone.app.collection" name="myview" for="plone.app.collection.interfaces.ICollection" class=".views.MyView" permission="zope2.View"/>
Registering an interface for new collection
<class class="plone.app.collection.collection.Collection"
zcml:condition="installed plone.app.collection">
<implements interface=".interfaces.IMyInterface" />
</class>
Retrieve the raw query
from plone.app.querystring import queryparser query = queryparser.parseFormquery(collectionobj, collectionobj.getRawQuery())
6.11. Upgrading Plone 4.2 to 4.3
6.11.1. Updating package dependencies
Plone 4.3's dependencies have been cleaned up so it pulls in fewer packages than Plone 4.2. If your add-on uses one of the packages that was removed, it needs to be updated.
Plone includes a couple hundred Python packages as dependencies. In recent history, many of these have been packages in the zope.app.* namespace that were not strictly necessary, but included as transitive dependencies of other packages. For Plone 4.3 we made a concerted effort to remove unnecessary dependencies.
This is great because it reduces Plone's baseline memory usage and speeds imports. But it does mean that any add-ons relying on the dependencies that were removed will need to make one of the following adjustments:
- Update imports to newer zope.* packages that have fewer dependencies, or
- Be sure to declare their dependency in the "install_requires" setting in setup.py
Here is a full list of packages that were automatically included in Plone 4.2 but no longer in Plone 4.3:
- elementtree (lxml is used instead)
- Products.kupu
- plone.app.kss (Can be added as an add-on to regain the inline editing feature. However it will no longer be maintained as a Plone core project.)
- zope.app.cache
- zope.app.component
- zope.app.container
- zope.app.pagetemplate
- zope.app.publisher
- zope.copypastemove
- zope.dublincore
- zope.hookable
The following table lists some commonly used imports that have new preferred locations. The last column has the minimum Plone version that you need for the new location to work.
| Name | Old location | New, preferred location | Minimum for new location |
|---|---|---|---|
| getSite, setSite |
zope.app.component.hooks zope.site.hooks |
zope.component.hooks | Plone 4.0 |
| IAdding | zope.app.container.interfaces | zope.browser.interfaces | Plone 4.1 |
|
IObjectRemovedEvent |
zope.app.container.interfaces | zope.lifecycleevent.interfaces | Plone 4.1 |
| INameChooser | zope.app.container.interfaces | zope.container.interfaces | Plone 4.1 |
| WidgetInputError | zope.app.form.interfaces | zope.formlib.interfaces | Plone 4.1 |
| contains | zope.app.container | zope.container | Plone 4.0 |
| contained | zope.app.container | zope.container | Plone 4.0 |
| ViewPageTemplateFile | zope.app.pagetemplate.viewpagetemplatefile | zope.browserpage.viewpagetemplatefile | Plone 4.1 |
6.11.2. Dexterity optional extras
Plone 4.3 includes Dexterity, but without Grok or support for relations. If you need those you must require them explicitly.
Plone 4.3 is the first Plone release to include the Dexterity content type framework in the core system. In Dexterity 2.0 - the version included in Plone 4.3 - some packages that were dependencies in Dexterity 1.0 are now optional extras. Therefore if you are upgrading from a previous Plone release with Dexterity installed, make sure you explicitly include those packages.
The easiest way to include the optional packages is by specifying an 'extra' for the plone.app.dexterity egg.
If you use Grok (five.grok, plone.directives.form or plone.directives.dexterity):
[instance]
eggs =
plone.app.dexterity [grok]
If you need support for relations:
[instance]
eggs =
plone.app.dexterity [relations]
Note that these may be combined:
[instance]
eggs =
plone.app.dexterity [grok, relations]
Don't forget to reinstall Dexterity from the Add-ons control panel.
For more information see Dexterity 2.0's release notes.
6.11.3. Changed imports and functions
Codebase changes needed to upgrade your addons for Plone 4.3 compatibility.
zope.app.component.hooks.setSite
Example:
try:
# Plone < 4.3
from zope.app.component.hooks import setSite
except ImportError:
# Plone >= 4.3
from zope.component.hooks import setSite # NOQA
zope.app.publisher.interfaces.IResource
Example:
try:
# Plone < 4.3
from zope.app.publisher.interfaces import IResource
except ImportError:
# Plone >= 4.3
from zope.browserresource.interfaces import IResource
plone.app.content.batching.Batch
Example:
try:
from plone.app.content.batching import Batch # Plone < 4.3
HAS_PLONE43 = False
except ImportError:
from plone.batching import Batch # Plone >= 4.3
HAS_PLONE43 = True
The two implementations have a different API.
The pagesize argument is named size in plone.app.batching; also, instead of a page number a start index is required.
If you have a piece of code like this:
b = Batch(items,
pagesize=pagesize,
pagenumber=pagenumber)
you should change it to look like this:
if HAS_PLONE43:
b = Batch(items,
size=pagesize,
start=pagenumber * pagesize)
else:
b = Batch(items,
pagesize=pagesize,
pagenumber=pagenumber)
plone.directives.form
You need to use special egg declaration:
eggs =
plone.app.dexterity [grok]
For more information see Dexterity info page on this manual.
five.intid and z3c.relationfield
If you get:
AttributeError: type object 'IIntIds' has no attribute 'iro'
or
AttributeError: type object 'ICatalog' has no attribute '__iro__'
include Dexterity with relations extras in buildout.cfg:
eggs =
plone.app.dexterity[relations]
See Dexterity migrations page for more information.
7. Upgrading Non-Buildout-based Plone Instances
How to upgrade versions of Plone that predate the use of buildout-based installers.
This document applies only to older Plone installations that do not use buildout. Generally, this means Plone 1 - Plone 3.x, although some custom installations of Plone 3 can be buildout-based. If you are using Plone 4, please see "General procedure for Plone 4.x minor version upgrades with buildout."
When upgrading to a newer release of Plone, it is important to run the content migration procedure, since internal structures in Plone might have changed since the last version. This is the general procedure for upgrading.
Before you start upgrading anything, make sure you have a backup.
The basic manual procedure is detailed below. If you are using the installers, you can skip the part about moving away directories and replacing them with the new ones (step 3-4) - it should be handled by the installer for you.
- Back up your entire Plone directory. If you're using WebDAV, make sure all objects are unlocked in Control Panel → WebDAV Lock Manager.
- Shut down your Plone server instance.
- Remove the Product directories you want to replace (ie. the ones in the package you downloaded).
- Put in the new Product directories.
- Start Plone again - your site may be inaccessible until we have performed the next steps - don't panic :)
- Go to http://yoursite/manage (aka. the ZMI) and click
portal_migrations - Make sure you are on the
Upgradetab (in older versions, this tab is calledMigrate) — it will state something like:Instance version: 2.5.3 File system version: 3.1.1 - This means that you have to run the upgrade procedure to be updated to 3.1.1.
- Click the
Upgradebutton.If you want to see what steps the upgrade would go through without making the actual changes, you can check the
Dry Runoption - this will do the exact same steps as a normal upgrade/migration will do, but not write anything to the database. - The site will now be updated, this may take a while, depending on which versions you upgrade from/to. For example, the upgrade from Plone 2.0 to Plone 2.1 involves conversion and re-cataloging of all content in your site, so if you have a big site, this may take a while. Be patient.
For those of you who wonder why we don't do this automatically, the reason is that we don't want to modify your data, and you should have the opportunity to back up the data before doing the upgrade.
For advanced/enterprise users: It is normally possible to upgrade in-place (at least between minor versions) without any site downtime if you run ZEO and multiple load-balanced instances. See the ZEO documentation for more information if you need this.
8. General advice on updating from a non-buildout to buildout-based installation
Some hints for those stepping onto the buildout bandwagon.
Beginning with Plone 3.2, we're no longer distributing Plone in the traditional tarballs (archive files) of Zope products. Instead, Plone is distributed as a set of Python Packages. These packages bear information about dependencies, and they generally provide us with a much better way of managing a complex web of Python, Zope and Plone components.
Buildout, a sophisticated configuration management system from the creator of Zope, is now the recommended way for managing Plone installations. This poses a one-time challenge for folks upgrading from old to new-style installs. It should, though, make future updates much easier.
The Managing projects with Buildout tutorial provides a great introduction to buildout and its use. Here, we'll just offer a few hints on making your move to buildout as painless as possible.
- Give up any idea of doing an in-place update. Many of us got into the habit with earlier versions of Plone of simply unpacking the tarball for a new version into the "Products" directory of the old install. That was never a good idea for a major version update, and it's just not feasible while trying to switch to buildout. The internal layout of the files has just changed too much. Changing to buildout will make it much easier, though, to upgrade in place in the future.
- Install a new, buildout-based Plone version to a different place than your old installation. Different path, different drive, different server, different hosting facility — whichever you need.
- Use a current Plone installer if available (all installers for 3.2+ are buildout-based):
- If you're using Linux/FreeBSD/*nix, please strongly consider using the Unified Installer. If you didn't like something about the way it worked for 2.x, please take a look again. It's a lot more versatile. It includes options to change target directory, do ZEO or stand-alone installs, and to use an already installed Python.
- If you're using Darwin on a production server, it's a good idea to install the XCode tools and use the Unified Installer. You'll want the versatility.
- If you're using OS X on a workstation, it's fine to use the OS X installer, which is meant to be convenient.
- If you're on Windows, use the Windows installer or prepare to learn a lot.
- If you're using Linux/FreeBSD/*nix, please strongly consider using the Unified Installer. If you didn't like something about the way it worked for 2.x, please take a look again. It's a lot more versatile. It includes options to change target directory, do ZEO or stand-alone installs, and to use an already installed Python.
- If you don't want to use an installer, that's OK, but protect your system Python. Learn to use virtualenv, which will allow you to create isolated Python sandboxes. Install virtualenv first, create a sandbox, then use easy_install in the sandbox to install ZopeSkel. Follow the buildout tutorial's instructions for creating your buildout.
- Fire up your new installation and make sure it's working. Try it out with an empty database. If you're using it on the same server, you should adjust the ports first to make sure you're not trying to use the same TCP/IP ports. This is a common error. Look for the "http-address" address in your buildout.cfg file. If you've used the Unified or OS X installers, it's even easier as the ports settings are in the top of the file.
- Evaluate your add-on product list. Enumerate all the add-on Zope and Plone products installed on your own server. Divide the list into those that have egg (Python Package) updates available and those that don't.
- Copy the add-on products that don't have egg versions from the "Products" directory of the old install into the "products" directory (note the small "p") of your new install. Check ownership and permissions of the copied files (failure to do this is another common error).
- Add the names of new, egg-based products to the "[eggs]" section of your buildout.cfg. Check the install instructions to see if they also need a ZCML slug specification. Re-run buildout to fetch and install the new eggs.
- Start your new install in foreground mode (bin/plonectl fg or bin/instance fg) to watch product loading and discover errors. Fix product problems until you have a clean start.
- Copy the Data.fs file from your old install's var directory to the new one's var/filestorage directory. Check ownership and permissions!
- Do the foreground start dance again. Solve problems.
- Go live.
A word on warnings
Whenever you run buildout and load new packages that have skin layers, you're likely to receive warnings indicating "'return' outside function." Ignore them, they're harmless. The warnings are produced when Python attempts to compile skin-layer Python scripts, which do indeed contain 'return' outside of function, but run in a context in which this is OK.

Author: