Personal tools
You are here: Home Documentation Manuals Plone Upgrade Guide Version-specific migration procedures and tips Upgrading Plone 2.5 to 3.0 Updating add-on products for Plone 3.0
Support

Get Help

Join our chat rooms or support forums if you have more specific questions.

Plone Training
Learn how to design, build, and deploy a website in Plone through one of the numerous Plone training sessions around the world.
Find Plone training…
 
Document Actions

Updating add-on products for Plone 3.0

Note: Return to reference manual view.

Procedures and tips for upgrading (aka. migrating) to a newer Plone version.

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
  • 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
    • Use Python Paste to create new packages
  • Suggestion: Use ploneit or ploneout to create development and/or production environments that can easily be replicated

For more information about using the new python packages please refer to the Guide to Python packages reference guide.

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.

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.

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.

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.

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 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 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 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.

7. Searching users/groups via the Membership tool is deprecated

Searching for users and groups using the portal_membership and portal_groups tools has been deprectaed. Please use the search features of PAS directly or the PlonePAS pas_search browser view.

XXX Need examples of this. (Wichert)

8. 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.

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.

XXX needs examples. (Martin?)

9. 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.

10. 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. :)

11. Plone Tableless theme no longer exists

The languishing tableless version of the Plone default theme has finally been removed from Plone 3.0.

For those of you who desire a tableless implementation of the default skin, please backport the markup changes to the new main_template.

NuPlone (the new theme in Plone 3.0) is a table-less alternative that we hope you like.

12. 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.

13. 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 for the changeset and full explanation.

14. 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 :

  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:

  <index name="getIssueType" meta_type="FieldIndex">
    <indexed_attr value="getIssueType"/>
  </index>

If there is also :schema or :metadata, e.g. index="FieldIndex:schema", you also need a metadata column:

  <column value="getIssueType"/>

This is necessary because the schema does not really exist at install time, so there is no way GenericSetup can inspect it and configure new indexes. This was a bad design from the start, as portal-wide indexes do not belong in type-specific schemata anyway.

15. 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. Of course, you may not need the References, History or External Edit actions in your own types.

16. 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.alsoProvides(MyContentType, IMultiPageSchema)

17. 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:

  <h1 tal:content="here/getSomeVariable" class="documentFirstHeading">
    Variable goes here
  </h1>

Now, to render the same thing, with an h1 tag and a class on it, you do:

  <h1 class="documentFirstHeading">
    <metal:field use-macro="python:here.widget('someVariable', mode='view')">
    Variable goes here
    </metal:field>
  </h1>

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.


For any issues with the web site functionality, please file a ticket.

Please consult the policy on plone.org content if you want your content published on this site.

Servers and hosting by