UGent University website migration to Plone 5.2
Plone Conference 2019 Ferrara
Andreas Jung

www.zopyx.com • info@zopyx.com
1
About Me
• Python since 1993
• Plone since 2002
• Publishing since 1995
• Plone migrations this year:
• ✅  2 larger custom Plone migrations to Plone 5.2, Python 3
• ✅ 7 smaller/medium migrations to Plone 5.1
• 🚧 4 other migrations to Plone 5.2, Python 3 planned
• contractor in current UGent Plone 5.2 migration project
2
Plone @ugent.be
• Ghent University, Belgium
• 44.000 students
• 9.000 staff members
• 500 active editors
• one large Plone site for all departments
• current state: Plone 4.3
• about 83 add-ons
• 69 subsites
• Size: about 90.000 content objects
• Languages: English, Dutch, (Korean) (no translation tool)
• Plone migration team: 6 persons (3 internal, 3 external)
3
Plone @ugent.be
• 2002: Zope/CMF
• 2007: Plone 2.5
• 2008: new theme
• 2010: Plone 3.3
• 2012: Plone 4.1
• 2015: Plone 4.3
• 2016: new theme
• 2019/2020: Plone 5.2/Python 3
4
Plone migration approaches
• traditional Plone in-place migration
• not applicable
• too many old add-ons, no 1:1 mapping possible
• Full export, full import using Transmogrifier
• not ready for Python 3 (6 months ago)
• too much magic hidden in too many places (blueprints)
• Full export, full import using a custom migration solution
• collective.jsonify → ArangoDB → plone.restapi
5
Add-ons @ugent.be
archetypes.markerfield
archetypes.schematuning
atreal.massloader
atreal.monkeyplone
collective.blog.portlets
collective.blog.view
collective.contentstats
collective.indexing
collective.keywordwidgetreplacer
collective.portlet.localsearch
collective.revisionmanager
collective.searchform
collective.setdefaulteditor
collective.tinymcetemplates
collective.topicitemsevent
collective.ZipFileTransport
p4a.plonecalendar
plone.app.changeownership
Products.CAS4PAS
Products.membrane
Products.OpenXml
Products.PloneFormGen
Products.RedirectionTool
munin.zope
Products.ZNagios
collective.portlet.localsearch
pyugent
ugent.api
ugent.authorship
ugent.cas_config
ugent.clearhistory
ugent.collectiondelete
ugent.configuration
ugent.contentfixer
ugent.customsearch
ugent.defaultpagechanged
ugent.editmode
ugent.folderdeleteconfirmation
ugent.foldersorting
ugent.forms
ugent.frameworkcontracts
ugent.helper
ugent.homepages
ugent.imagelibrary
ugent.librarywidgets
ugent.ldap
ugent.linkchecker
ugent.membrane
ugent.metadata
ugent.pas.ldap
ugent.patches
ugent.phddefense
ugent.phonebook
ugent.plone4theme
ugent.plone4translations
ugent.policy
ugent.portlet.banner
ugent.portlet.collection
ugent.portlet.infolinks
ugent.portlet.links
ugent.portlet.slideshow
ugent.portlet.socialbanner
ugent.portlet.twitter
ugent.portlets
ugent.provisionalcontent
ugent.removemarkers
ugent.reporting
ugent.review
ugent.rss
ugent.sharing
ugent.stalecontent
ugent.subsites
ugent.supergroup
ugent.textindex
ugent.tinymce
ugent.unavailable
ugent.vacancy
ugent.vocabularies
mailinglogger
collective.z3c.keywordwidget
qi.portlet.TagClouds
eea.facetednavigation
raven
6
Content types @ugent.be
• standard Plone types
• custom content-types
• PloneFormGen
• PhdDefense
• Vacancy
• LibraryDocument
• extensive usage of schema extenders
7
Analyze and investigate

your dependencies
• check your packages for Python 3 compatibility (setup.py)
• check for Python 3/Plone 5.2 related branches
• drop any package related to Archetypes or other Python 3
incompatible dependencies
• drop packages are not no longer needed or are obsolete
• check for package alternatives 

(PloneFormGen → collective.easyform)
8
Document your insights
9
Create your target setup
• start with a minimal Plone 5.2 buildout
• add one verified Python 3 compatible 

add-on at a time
• test, test, test _manually_
• focus on content-types first
• configurations, decorations, extra functionality next
10
@ugent.be migration export
• customized version of collective.jsonify:
• full-export of all content objects

and their properties
• export of portlet assignments
• default pages, layout information
• workflow states
• local roles (@@sharing)
• pre-computed values for further
efficient processing
• 90.000 content objects
• 90.000 JSON files
• 55 GB data
• 90 minutes
• binaries b64 encoded
11
ArangoDB migration DB
Why a migration database?
•we want to run partial imports (e.g. importing a particular subtree of the original
site)
•we want to test a particular migration feature e.g. a complex migration step 

(PloneFormGen to EasyForm)
•Easy query and check the original data (just a query by path)
Why ArangoDB?
• 👻 because MongoDB sucks (16 MB BSON limit) 👻
•Multi-model database: key-value, document, graph
•dedicated DSL AQL (Arango Query Language) vs. JSON-based queries (ES,
MongoDB…)
•easy to install and use
•JSON files can be dumped into ArangoDB without modifications
•import time: about 45 minutes
•successfully used in previous Python projects
12
ArangoDB migration DB
13
Import infrastructure
• clean Python 3.7, Python 5.2 buildout
• import via plone.restapi
• dedicated migration package with specific views for functionality that is not provided by
plone.restapi or specific to the migration project
• path to UID in RichText fields
• setting INavigationRoot
• setting position in parent
• allowed/addable types per folder (folder restrictions)
• setting related items (as post migration operation)
• setting permissions and roles
• setting marker interfaces
• adding portlets
14
• YAML based configuration
The "magic" migration script (1/3)
15
The "magic" migration script (2/3)
• Phase 1 (migration setup &preparation)
• migration pre-check
• removal of target site (if existing)
• creating a new fresh Plone 5.2 site with a given number of
extension profiles
• Phase 2 (folders)
• query ArangoDB for all folderish types
• rebuild complete folder structure with full metadata, workflow
information
16
• Phase 3 (non folders)
• query ArangoDB for all non-folderish types
• add non-folderish content as leafs to existing folder
structure
• Phase 4 (global actions)
• path to UID check/migration for RichText fields
• assignment of portlets
• some specific fixup operations
The "magic" migration script (3/3)
17
PloneFormGen to EasyForm
• PloneFormGen no longer available under Plone 5.2/Python 3 

(Archetypes dependency)
• collective.easyform as replacement (Dexterity-based clone of PFG)
• PFG export: one JSON for FormFolder and 1..N JSON for all fields and
mail, save and script adapter
• fields and actions are defined in collective.easyform as a schema
• extract relevant metadata for EasyForm from all JSON files
• build supermodel XML files for fields and actions from all JSON files
• instantiate EasyForm instance and assign fields + actions supermodel
18
Topics to Collections
• Topics export: one JSON for ’Topic’ and 1..N
JSON file for each criteria
• Conversion of old-style topic criteria to
plone.app.querystring
• basically based on original migration code of
Plone
• instantiate Collection and assign query strings
19
From schema extenders 

to behaviors
1. documentation and analysis of all schema
extenders, their usage
2. check with Dexterity replacements
3. reimplementation as behaviors
Issues
• customizing of existing behaviors painful
• bunch of monkey-patches or code duplication
20
Migrating packages to Python 3
• mostly covered by talks of Philipp Bauer and David Glick
• most common problems:
• fixing UTF-8 vs. unicode related code
• import fixes
• @implements -> @implementer
• rarely used 2to3 or moderinzr
• no need to maintain both Python 2 and Python 3 compatibility
• usually created a dedicated Plone52Python3 branch from the current master
• unit tests if available
• basic manually testing
21
Reimplementations
• historic code in portal_skins replaced with
browser views → reimplementation
• core Archetypes-based content-types
replaced with Dexterity → reimplementation
22
Other common problems
• improper image/file metadata in blobs 

(TIFF stored as some.jpg, image/jpeg)
• migration on vocabulary values 

(e.g. old to new departments)
• there is always one more thing missing in your export
(repetitive export/import cycles)
• there is always one more bug in your migration script
(portlets, collections)
23
Quality control
• aspects
• completeness of content and configurations
• consistency of migration (systematic errors)
• too many tiny aspects slipping out of our focus
• unit tests if available
• manual testing by different persons
• "works for me" does not mean that it works for others
24
Add-ons @ugent.be (old)
archetypes.markerfield
archetypes.schematuning
atreal.massloader
atreal.monkeyplone
collective.blog.portlets
collective.blog.view
collective.contentstats
collective.indexing
collective.keywordwidgetreplacer
collective.portlet.localsearch
collective.revisionmanager
collective.searchform
collective.setdefaulteditor
collective.tinymcetemplates
collective.topicitemsevent
collective.ZipFileTransport
p4a.plonecalendar
plone.app.changeownership
Products.CAS4PAS
Products.membrane
Products.OpenXml
Products.PloneFormGen
Products.RedirectionTool
munin.zope
Products.ZNagios
collective.portlet.localsearch
pyugent
ugent.api
ugent.authorship
ugent.cas_config
ugent.clearhistory
ugent.collectiondelete
ugent.configuration
ugent.contentfixer
ugent.customsearch
ugent.defaultpagechanged
ugent.editmode
ugent.folderdeleteconfirmation
ugent.foldersorting
ugent.forms
ugent.frameworkcontracts
ugent.helper
ugent.homepages
ugent.imagelibrary
ugent.librarywidgets
ugent.ldap
ugent.linkchecker
ugent.membrane
ugent.metadata
ugent.pas.ldap
ugent.patches
ugent.phddefense
ugent.phonebook
ugent.plone4theme
ugent.plone4translations
ugent.policy
ugent.portlet.banner
ugent.portlet.collection
ugent.portlet.infolinks
ugent.portlet.links
ugent.portlet.slideshow
ugent.portlet.socialbanner
ugent.portlet.twitter
ugent.portlets
ugent.provisionalcontent
ugent.removemarkers
ugent.reporting
ugent.review
ugent.rss
ugent.sharing
ugent.stalecontent
ugent.subsites
ugent.supergroup
ugent.textindex
ugent.tinymce
ugent.unavailable
ugent.vacancy
ugent.vocabularies
mailinglogger
collective.z3c.keywordwidget
qi.portlet.TagClouds
eea.facetednavigation
raven
25
Add-ons @ugent.be (new)
Products.PloneKeywordManager
eea.facetednavigation
collective.siteimprove
collective.blog.portlets
collective.portlet.localsearch
ugent.customaddforms
ugent.forms
ugent.imagelibrary
ugent.librarywidgets
ugent.phddefense
ugent.phonebook
ugent.plone5migration
ugent.policy
ugent.portlet.collection
ugent.portlet.infolinks
ugent.portlet.links
ugent.portlet.slideshow
ugent.portlet.socialbanner
ugent.portlet.twitter
ugent.showlabel
ugent.subsitefolder
ugent.textindex
ugent.vacancy
plone.app.changeownership
26
Current status/open issues
• Content migration almost complete
• next: detailed testing needed
• next: integration with updated UGent theme and theme
testing
• open:
• replacement of a specific Membrane usage
• collective.castle, Products.CAS4PAS
27
Takeaways
• Export Plone → JSON: 2 hours (fast)
• Import JSON → ArangoDB: 45 mins (fast)
• Import ArangoDB → plone.restapi: 36-48 hours (painfully slow)
• 1,5-2,0 seconds per content object in average
• no option for parallelization (risk of write conflicts)
• CREATE most expensive operation
• Plone/Zope/ZODB are painfully slow backends for "mass" content
28
Questions?
29

More Related Content

PDF
Plone migrations using plone.restapi
PDF
Docker and Fluentd
PPTX
Auto-Generating Language-Specific Wrappers for Rust Libraries
PDF
.NET Core Blimey! (dotnetsheff Jan 2016)
PDF
ODP
Pywps a tutorial for beginners and developers
PDF
All of the thing about Postman
PDF
.NET Core Blimey! Windows Platform User Group, Manchester
Plone migrations using plone.restapi
Docker and Fluentd
Auto-Generating Language-Specific Wrappers for Rust Libraries
.NET Core Blimey! (dotnetsheff Jan 2016)
Pywps a tutorial for beginners and developers
All of the thing about Postman
.NET Core Blimey! Windows Platform User Group, Manchester

What's hot (20)

PDF
How to create/improve OSS product and its community (revised)
PPTX
Super Size Your Search
PDF
Continuing Evolution of Perl: Highlights of ActivePerl 5.14
PDF
Apache ManifoldCF
PDF
[Mentor Graphics] A Perforce-based Automatic Document Generation System
PDF
PyWPS-4.0.0
PPTX
Repeating History...On Purpose...with Elixir
PDF
Solr and ManifoldCF
PDF
Flink Forward San Francisco 2019: Elastic Data Processing with Apache Flink a...
PPTX
Tuenti Release Workflow
PPTX
Robotframework
PDF
Git, from the beginning
PDF
Flink Forward San Francisco 2019: The Trade Desk's Year in Flink - Jonathan ...
PDF
.Net standard 2.0
PPTX
Introduction to Git / Github
PDF
[Lucas Films] Using a Perforce Proxy with Alternate Transports
KEY
Firefox Crash Reporting (@ Open Source Bridge)
PPTX
ITB2015 - Go Commando with CommandBox CLI
PPTX
Apache flink 1.0.0 overview
PPTX
GIT presentation
How to create/improve OSS product and its community (revised)
Super Size Your Search
Continuing Evolution of Perl: Highlights of ActivePerl 5.14
Apache ManifoldCF
[Mentor Graphics] A Perforce-based Automatic Document Generation System
PyWPS-4.0.0
Repeating History...On Purpose...with Elixir
Solr and ManifoldCF
Flink Forward San Francisco 2019: Elastic Data Processing with Apache Flink a...
Tuenti Release Workflow
Robotframework
Git, from the beginning
Flink Forward San Francisco 2019: The Trade Desk's Year in Flink - Jonathan ...
.Net standard 2.0
Introduction to Git / Github
[Lucas Films] Using a Perforce Proxy with Alternate Transports
Firefox Crash Reporting (@ Open Source Bridge)
ITB2015 - Go Commando with CommandBox CLI
Apache flink 1.0.0 overview
GIT presentation
Ad

Similar to Plone 5.2 migration at University Ghent, Belgium (20)

PDF
Introduction to Python and Django
PPTX
Python and GIS: Improving Your Workflow
PDF
Embedded Systems: Lecture 10: Introduction to Git & GitHub (Part 1)
PPTX
Git version control and trunk based approach with VSTS
PDF
DanNotes 2013: OpenNTF Domino API
PDF
Pharo 11: A stabilization release
PPTX
Symfony under control. Continuous Integration and Automated Deployments in Sy...
PPTX
Symfony Under Control by Maxim Romanovsky
PDF
It's the way of the present - Why you should use plone.app.contenttypes
PDF
Python indroduction
 
PDF
Pharo 10 and beyond
PDF
Steamlining your puppet development workflow
PDF
Puppet Camp New York 2014: Streamlining Puppet Development Workflow
PPTX
They why behind php frameworks
PDF
TYPO3 Transition Tool
PDF
Spring Roo Add-On Development & Distribution
PPTX
python.pptx
PPTX
Nagios Conference 2014 - Mike Merideth - The Art and Zen of Managing Nagios w...
PPTX
Using puppet, foreman and git to develop and operate a large scale internet s...
PDF
Fedora4
Introduction to Python and Django
Python and GIS: Improving Your Workflow
Embedded Systems: Lecture 10: Introduction to Git & GitHub (Part 1)
Git version control and trunk based approach with VSTS
DanNotes 2013: OpenNTF Domino API
Pharo 11: A stabilization release
Symfony under control. Continuous Integration and Automated Deployments in Sy...
Symfony Under Control by Maxim Romanovsky
It's the way of the present - Why you should use plone.app.contenttypes
Python indroduction
 
Pharo 10 and beyond
Steamlining your puppet development workflow
Puppet Camp New York 2014: Streamlining Puppet Development Workflow
They why behind php frameworks
TYPO3 Transition Tool
Spring Roo Add-On Development & Distribution
python.pptx
Nagios Conference 2014 - Mike Merideth - The Art and Zen of Managing Nagios w...
Using puppet, foreman and git to develop and operate a large scale internet s...
Fedora4
Ad

More from Andreas Jung (20)

PDF
A fool with a tool is still a fool - Plone Tagung 2025 in Koblenz
PDF
zopyx-fastapi-auth - authentication and authorization for FastAPI
PDF
State of PrintCSS - MarkupUK 2023.pdf
PDF
Typesense Plone Integration Plone Conference 2022 Namur
PDF
Onkopedia - Plone Tagung 2020 Dresden
PDF
PrintCSS W3C workshop at XMLPrague 2020
PDF
PrintCSS workshop XMLPrague 2020
PDF
Back to the future - Plone 5.2 und Python 3 Migration am Beispiel Onkopedia
PDF
Plone Migrationen mit Plone REST API
PDF
Plone im Einsatz bei der Universität des Saarländes als Shop-System und Gefah...
PDF
Generierung von PDF aus XML/HTML mit PrintCSS
PDF
Creating Content Together - Plone Integration with SMASHDOCs
PPTX
Creating Content Together - Plone Integration with SMASHDOCs
PDF
The Plone and The Blockchain
PDF
Content Gemeinsam Erstellen: Integration Plone mit SMASHDOCs
PDF
PDF Generierung mit XML/HTML und CSS - was die Tools können und was nicht.
PDF
Why we love ArangoDB. The hunt for the right NosQL Database
PDF
XML Director - the technical foundation of onkopedia.com
PDF
PyFilesystem
PDF
Building bridges - Plone Conference 2015 Bucharest
A fool with a tool is still a fool - Plone Tagung 2025 in Koblenz
zopyx-fastapi-auth - authentication and authorization for FastAPI
State of PrintCSS - MarkupUK 2023.pdf
Typesense Plone Integration Plone Conference 2022 Namur
Onkopedia - Plone Tagung 2020 Dresden
PrintCSS W3C workshop at XMLPrague 2020
PrintCSS workshop XMLPrague 2020
Back to the future - Plone 5.2 und Python 3 Migration am Beispiel Onkopedia
Plone Migrationen mit Plone REST API
Plone im Einsatz bei der Universität des Saarländes als Shop-System und Gefah...
Generierung von PDF aus XML/HTML mit PrintCSS
Creating Content Together - Plone Integration with SMASHDOCs
Creating Content Together - Plone Integration with SMASHDOCs
The Plone and The Blockchain
Content Gemeinsam Erstellen: Integration Plone mit SMASHDOCs
PDF Generierung mit XML/HTML und CSS - was die Tools können und was nicht.
Why we love ArangoDB. The hunt for the right NosQL Database
XML Director - the technical foundation of onkopedia.com
PyFilesystem
Building bridges - Plone Conference 2015 Bucharest

Recently uploaded (20)

PPTX
IT-Human Computer Interaction Report.pptx
PPTX
北安普顿大学毕业证UoN成绩单GPA修改北安普顿大学i20学历认证文凭
PDF
How Technology Shapes Our Information Age
PDF
Testing & QA Checklist for Magento to Shopify Migration Success.pdf
PDF
ilide.info-huawei-odn-solution-introduction-pdf-pr_a17152ead66ea2617ffbd01e8c...
PPT
Expect The Impossiblesssssssssssssss.ppt
PPTX
Going_to_Greece presentation Greek mythology
PPTX
PORTFOLIO SAMPLE…….………………………………. …pptx
PPTX
Basic_of_Computer_System.pptx class-8 com
PPTX
最新版美国埃默里大学毕业证(Emory毕业证书)原版定制文凭学历认证
PPTX
Digital Project Mastery using Autodesk Docs Workshops
PPT
chapter 5: system unit computing essentials
PPTX
Concepts of Object Oriented Programming.
PDF
Lesson.-Reporting-and-Sharing-of-Findings.pdf
PPTX
Networking2-LECTURE2 this is our lessons
PPTX
National-Historical-Commission-of-the-PhilippinesNHCP.pptx
PDF
healthwealthtech4all-blogspot-com-2025-08-top-5-tech-innovations-that-will-ht...
DOCX
Audio to Video AI Technology Revolutiona
PPTX
Data Flows presentation hubspot crm.pptx
PDF
B450721.pdf American Journal of Multidisciplinary Research and Review
IT-Human Computer Interaction Report.pptx
北安普顿大学毕业证UoN成绩单GPA修改北安普顿大学i20学历认证文凭
How Technology Shapes Our Information Age
Testing & QA Checklist for Magento to Shopify Migration Success.pdf
ilide.info-huawei-odn-solution-introduction-pdf-pr_a17152ead66ea2617ffbd01e8c...
Expect The Impossiblesssssssssssssss.ppt
Going_to_Greece presentation Greek mythology
PORTFOLIO SAMPLE…….………………………………. …pptx
Basic_of_Computer_System.pptx class-8 com
最新版美国埃默里大学毕业证(Emory毕业证书)原版定制文凭学历认证
Digital Project Mastery using Autodesk Docs Workshops
chapter 5: system unit computing essentials
Concepts of Object Oriented Programming.
Lesson.-Reporting-and-Sharing-of-Findings.pdf
Networking2-LECTURE2 this is our lessons
National-Historical-Commission-of-the-PhilippinesNHCP.pptx
healthwealthtech4all-blogspot-com-2025-08-top-5-tech-innovations-that-will-ht...
Audio to Video AI Technology Revolutiona
Data Flows presentation hubspot crm.pptx
B450721.pdf American Journal of Multidisciplinary Research and Review

Plone 5.2 migration at University Ghent, Belgium