Category Archives: plone-cms

Redirection in WordPress for the Plone URLs

The python-based import script which I used to automatically import my plone content into wordpress – see the coresponding article here – also generates an output file where for all content items, i.e. for pages, posts and blobs, the mapping between plone URL and wordpress URL and wordpress ID is stored.

Using this rather extensive file a quick python script is used to extract the two relevant sections for redirections, i.e. the mapping plone URL <> wordpress URL

  • for pages and posts
  • for blobs aka media

The script also updates and reformats the input such that the resulting two files pagePostMap.csv, blobMap.csv can be directly imported into the Redirection Plugin of wordpress.

Download the script here:

plone2wordpress redirections


WordPress – Fixing Things

Well, it took me a while to comlete the final post about the  migration from plone to wordpress. But here it is, where I outline the finishing touches to get a fully working site. For background information, please read the previous posts about the intermediate data export from plone to the file system. and the automated import into wordpress.

Content Listings

For folderish objects plone can automatically create content listings in various styles. These listings show the content of the folder or the result of some query definition. WordPress – in contrast – is not aware of a strict folder hierarchy and content and therefore is not able to generate these listings.

What to do?

For a website of moderate size like I resorted to manually creating these content listings after import into Wordpres. For this purpose the export automatically detects objects with content listings and sets the content to some predefined statement (“Directory listing missing”. After import a quick search for this statement quickly gives all pages where a manually created listings needs to be defined.

The folder listings are directly copied from the plone instance which during migration was running in parallel. There is hence no specific need to manually recreate these listings.

Trouble with Plone Aquistion

Generally defined, Plone’s aqusition is a functionality where objects can aquire any property from any parent. What this means is that e.g. if a link references an image by name, but the image is located in one of the parent folders than plone automatically subsequently searches all parent folders for said image.

Under plone the majority of posts where written manually using the restructured text syntax. Here, I used aquisition for many links to reduce link lengths and to avoid excessive typing.

Again – What to do?

There probably are some plone commands to automatically check all links and to convert aquisitioned links to directly link to the real object. But this would mean at least an additional export step and some handling around with the plone code base.

For I – once again – resorted to keeping the links as is upon export and import. After import broken links are detected using the excellent Broken Link Checker Plugin in WordPress and are fixed manually by deleting the additional sub folder items in the link.

All in all this required about 2 hours for my site (and therefore was probably more efficient than mucking around with plone python code)

Handling Files, Images and Image Sizes

For all images uploaded to  plone website, various sizes are available by adding e.g. <link>/image_thumb to a link. In wordpress things are handled differently via media elements.

As I did not want to manually change all links to specific images sizes and to other files etc. I created a static mirror of the plone website via wget and copied the downloaded version to a separate subdomain.

A set of rewrite rules takes care of the rest, see below. All links to images are transparently redirected to the archive version of plone.

 # BEGIN WordPress
 <IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 # Plone images are served from static mirror (mz, 2014.07)
 RedirectMatch (.*)image_(.*)$1image_$2
 RedirectMatch (.*)/view$1/image_preview

 # Plone - Map all jpg images in content directories to default plone variant image_preview
 RedirectMatch /projects/(.*).jpg$1.jpg/image_preview
 RedirectMatch /restricted/(.*).jpg$1.jpg/image_preview
 RedirectMatch /travel/(.*).jpg$1.jpg/image_preview
 RedirectMatch /work/(.*).jpg$1.jpg/image_preview

Plone to WordPress: Importing Data into WordPress

This is Part 3 of the documentation of my migration from plone to wordpress. Read the previous posts for my reasons to choose wordpress as CMS of choice and about the intermediate data export from plone to the file system.

General Approach

As outlined in my previous post all data from the plone site is exported to an intermediate data represenation on the local file system in JSON format.

For the data import the excellent XML-RPC capabilities of wordpress are used. This interface allows the script-controlled creation of content in any given wordpress site. For python, there is the excellent python-wordpress-xmlrpc library  that comes with a pretty good documentation.

For the import I developed a python script which sequentially reads the JSON-data from my local harddrive, analyzes each entity and creates the corresponding wordpress content objects.

Python-Script for Import

The import script I developed and used as part of my migration process is written in python and uses the coresponding xml-rpc library. The basic functionality is as follows:

  • WordPress pages are created for all Plone Articles. For folderish items the default content item is used or – if no item present – an empty page with a user-defined text is created.
  • WordPress blog posts are created for all Plone NewsItems. Categories are defined according to the tags of the plone newsitem.
  • For all blobs i.e. for file items and images files are uploaded and corresponding landing page with a link to the uploaded files are generated. The creation of landing pages can be enabled or disabled via an option.

All content items are created with the correct creation, publication and modification data. If wanted, a mapping table between plone URL and wordpress URL (and id) is written during import in CSV format . This file can be used to define redirections using e.g the redirection plugin for wordpress.

The script is available for download:

python import script

Please configure the script according to your needs. The configuration options are at the top of the script.

Next Steps

With the data imported into wordpress the final step of the migration from plone to wordpress  means to fix all things that need fixing. It is time to wrap things up.

Plone to WordPress: Exporting Data from Plone

This is Part 2 of the the documentation of my migration from plone to wordpress. Read the previous post for my reasons to choose wordpress as CMS of choice.

As there is no direct path for a migration from Plone to some of the PHP-based content management systems I choose to follow a route which I had previously used quite sucessfully for other problems, namely to use an intermediate representation.

Script-based Export to JSON Data

Out of the box plone supports various methods for export either directly or via third-party products. From my quick research it seems as if many of these approaches do not really apply to the current plone 4 or require a substantive amount of plone developers knowledge which I don’t have. Other methods exported the data to XML with quite complex data structures.

What I found – though – are various approaches that export plone data to JSON files.There is

  1. a post Exporting Plone content as JSON which  presents a nice and simple python script for JSON export,
  2. collective.jsonify which up to just recently did not support blob fields,
  3. collective.jsonmigrator which is a tool for migration from plone 2.x sites to plone 4.0.
  4. collective.blueprint.jsonmigrator which publishes a set of blueprints for the migration from plone 2.x to plone 4.0

For my purpose I used the blueprint export script from collective.blueprint.jsonmigrator as starting point.  In a series of iterations I modified this script such that I had an export run without an error. As a result for every data object (articles, pages, images, files) in plone I get a separate json file. For objects with binary data an additional base64-encoded data file is created, too.


Yes, there are . All items that are non-content objects in plone (users, css module, etc.) are skipped. Non-ascii characters anywhere expect the main body text are not supported. Workflow states and security permissions are disabled and hence not exported in my version.

You can get my version of the export script here:

Copy the python file to your plone installation and add an external method pointing to this script’s export_plone20 function.

FTP Access

In addition to the JSON export I used the FTP access to the plone instance to get a direct copy of all data as present in the instance. This gives the files without any content information like title, publication date etc. yet with their file names as given in plone. For articles or blog entries text files are returned which contain title, teaser text, body text and author, publication date, etc.

For artictles written in restructured text the retrieved text files contained this restructured text and not the corresponding (rendered) representation. Not that helpful.

HTTP Mirroring

Finally, I used the excellent wget tool to also get a direct export of the complete website as visibile via http. This returned not only the unchanged image files as via ftp access but also the automatically generated variants for thumbnails, preview or fullscreen perspective.

Next Steps

With the data exported the next steps of the migration from plone to wordpress are:

  • Importing data into wordpress
  • and wrapping everything up.

Migrating from Plone to WordPress

Over the last 7 years was using Plone as CMS of choice. But not anymore. Over the last couple of weeks I migrated the website to WordPress.


Well, first let me stress that I never encountered any serious problems with my Plone site. Yet, over the last couple of years Plone has become more and more complex with a rapid succession of new technologis, complex xml-based configurations and layers upon layers of abstraction. All this added up to an application stack which is very difficult to understand and maintain. Starting with Plone 3 upgrades have become frustating and error prone. The constant introduction of new technologies are only manageable with continuous learning and with continuous development work. Time which I do not want to invest.

Early this year I finally had a site which was running flawlessly yet which I could not update due to my limited knowledge. At the same time I could not reinstall the site in the current configuration as certain packages where not available any more. This gave me a system which I neither could restore in case of a server crash nor which I could maintain for the future in one way or the other. Therefore, it was time to move on. The results you can see here.

The migration from Plone to WordPress was a four step process, namely:

    1. Selecting WordPress as CMS
    2. Exporting the data from Plone
    3. Importing the data to Worpress
    4. Fixing things
    5. Addon; Redirections in Worpress for Plone URLs

The general migration process will be outlined here including all scripts developed for this purpose.

Plone 4 Galleries – An Overview

This started as a personal documentation long time ago… may be it is useful for soemeone 🙂

For Plone 4 a bunch of different gallery products are available. Having tested most of them, see the products section, for the following two products were chosen:

As personal documentation and may be as help for other interested users, in the following different usage scenarios for these two products are shown.

Plain Galleries

This is probably the most common and simple use case where a bunch of images residing in a common folder should be shown as gallery. For this purpose, both products provide the corresponding views as shown

  • here for collective.prettyphoto
  • and here for collective.plonetruegallery.

As the album view only shows 12 images on each page (batched), prettyPhoto only shows 12 images at one go. Then you have to select the next page, see this bug report

For plonetruegallery, please see the settings tab (display type: highside or Fancy Box)

Handling Individual Images

Often, on an indivdual page, small images are shown which are then linked to the full size version which, when clicked, show up some enlarged lightbox overlay. For this purpose, on the functionality offered by collective.prettyPhoto is used where two different approaches are avaiabele

Rel Statement

Either use the approach mentioned in the prettyphoto documentation and add a rel=prettyPhoto argument to your href statement as follows

<a href="path/to/image/fullsize" rel="prettyPhoto">Title for the Link</a>

and you get:

  • Example

Css Statement

Alternatively, you can mark your href statement and use the css class prettyPhoto prodived by prettyPhoto for this purpose. Your html code hence looks as follows

<a title="PrettyPhoto Overlay Test for Single Image Using a CSS Class" 
class="prettyPhoto" href="path/to/image/fullsize">Example</a>

and results in:

Galleries for Multiple Images

If the page contains multiple images, you might want to show a gallery overlay where you can browse through such a set of images. For this purpose prettyPhoto offers an solution as follows:

<a href=/path/to/image1/fullsize" rel="prettyPhoto[ImageSetName]">Image 1</a> 
<a href=/path/to/image2/fullsize" rel="prettyPhoto[ImageSetName]">Image 2</a>

Here, a set of images is defined by the statement rel=”prettyPhoto[galleryName]”. In a single page, different independent sets of images can be defined. Upon calling a single link, prettyPhoto presents a navigation over all images of the selected set.

  • Example:
    Image 1 Image 2

Tip: If you want only a single visible image yet would like to present a navigation over multiple images, add the other links with empty <a > tags or with blanks.

Links to Complete Galleries

Assume that you have a folder with a set of images somewhere in your site that you want to link to. As a result, you would like to see some gallery overlay (lightbox style) when you activate this link. Herefore, with the products described two different solutions are possible.


Link to the folder containing the images. Here, the user can start the overlay gallery manually


Use the @@placegalleryview view provided by collective.plonetruegallery while using the prettyPhoto overlay IFrame. This can be done as follows

<a class="prettyPhotoIframe" href="/path/to/image/folder/@@placegalleryview">Link Name</a>

which gives:

Embedding Galleries

Finally, embedding a gallery representation in a page is currently not supported by prettyPhoto. Personally, I doubt that this is feasible, as prettyPhoto mandated that for all images links are present somehwere on the page.

Yet, there is collective.plonetruegallery to the rescue.

<object data="/path/to/image/folder/@@placegalleryview" height="400"  width="500">
<param name="data" value="/path/to/image/folder" />

And don’t forget to update safe_html as mentioned in the documentation. Namely, change the following

  • nasty_tags: object = 0
  • valid_tags: object = 1, param = 1


  • prettyPhoto: Currently, a plonetruegallery overlay linking to a complete set of images (Example) may lead to nasty scrollbars. This is due to prettyPhoto.js script not adhering to the prettyPhoto properties defined in portal_properties (width, height), see this bug report.
    ><b>Update 201107/13: It seems this issue can be solved by updating the css registry, see the this bug report.
  • prettyPhoto: Find a way to directly embed the prettyPhoto view into a page without referencing all the other images somehow. Maybe use the API and provide the list of images as argument. This list could be populated by javacscript somehow…

On towards Plone 4

Yes, is now running with Plone 4.

As the database of this site dates back to the Plone 2.0.x, this required quite some preparatory work. But after some initial fiddling around everything worked out quite nicely, as can be seen in my upgrade notes. Also, the skin was updated to incorporate some changes required for plone 4 compatibility, see the svn repository

And now? Well, we have a current and up-to-date system where things like improved galleries (collective.prettyphoto for single galleries and collective.plonetruegallery for inline galleries, see the hidden features section) will actually work. We will see.

An Upgrade to Plone 4 – Random (Personal) Notes

With Plone 4 being released for quite a while and with some free time at my hands I took some initial stabs at a migration or update of my site which is currently running Plone 3.2.x. Here, some random notes about the first results:

  • The current theme won’t work. Peroid. This theme was created using the standard approach with paster. And I still don’t have any clue what need’s to be changed to remedy this. As an alternative, some xdv-based theme might be an option.
  • If your migration script fails and shows you some error regarding “Object not found”, then a broken index might be the issue at hand. And if you still happen to have one of the old TextIndex.TextIndex” indexes in your catalog, a simple rebuilt won’t help. Better delete the corresponding index and replace it with a ZCTextIndex index, rebuild, voila, see my post Upgrade from 3.2.2 to 4.0.2 fail on the Plone Setup mailing list.
  • Currently, all pages here are written as restructured text. With the advent of TinyMCE as editor, I might even go for a graphical editor. For this purpose, yet, all existing documents need to be converted to the html-format. More information? See here (in german)
  • After migration, the workflow state needs to be fixed somehow. Currently, all items show up in the review list yet even if they do have a “published” state. Retracting and republishing is not an option as then all the creation and modification time data etc. will be changed. This is still an item for further evaluation.

Anyway, this concludes my personal experiences. So much for now.