Canonical has used a variety of content management systems throughout the years, including Drupal and Zope, and a large number of our websites have run on WordPress; in fact, many still do. Our developer portal was one of these standard WordPress instances, which worked well enough for a simple website that didn't get very heavy traffic, but we began to outgrow it. The launch of the Ubuntu phone project, and its accompanying SDK for app development, meant that this site was going to start getting a lot more attention—from a very different audience—and it needed to do a lot more than it currently did.

Building new features on top of WordPress has been difficult for us in the past, so we mostly stuck with what we got from a vanilla install. That approach wasn't cutting it anymore; we had too many things we wanted to do that we simply couldn't. When we wanted to add API documentation, we ended up building a whole new site based on Django to do it, and simply bypassed the WordPress site all together.

Additionally, we had all new requirements for the availability of the site. High Availability (HA) we knew how to do, but it meant moving from a single server instance into the cloud, specifically, into our private OpenStack cloud. To serve China users efficiently, we also had to provide a local caching server within the country. Both of these were going to require a drastic change to the infrastructure backing the site.

And finally, among all of the many new technical requirements was a social one. We were launching our second phone with Meizu in China, and they wanted to have apps that targeted and supported Chinese users. To make that happen, we would be running an app developer contest and a series of workshops in collaboration with China Mobile. This meant that we had to make the whole site available in Chinese, in addition to English, something WordPress couldn't do out of the box. So we started looking for alternatives.

CMS options

There are many options when it comes to open source content management, and we looked into as many of them as we could find. Every one had its pros and cons, and fell somewhere in the spectrum between simplicity and capabilities. We considered everything from static website generators, to writing something new from scratch, then back again. Although there was no perfect solution, we found that DjangoCMS stood out from the rest.

WordPress was our baseline for feature comparisons, and DjangoCMS provided almost all of the same functionality. DjangoCMS provides easy management of page content and navigation, user and group administration, a WYSIWYG editor (when using djangocms_text_ckeditor), and a blog system (by pairing up with Zinnia). It also offered features that stock WordPress didn't. First is internationalization support, which DjangoCMS provides for page content and navigation right out of the box. Using Django also meant that we could use our preferred database, PostgreSQL, instead of MySQL. DjangoCMS even provides a more extensive system of permission and access controls would allow giving different groups the ability to manage different parts of the site.

Deciding on a Django-based option worked out especially well for us, because Canonical has built up a large amount of knowledge and experience using Django and Python, far more than we had with WordPress and PHP. We even had existing web themes for Django's templating system, and django_openid_auth, which allows us to use Ubuntu SSO for user and group authentication. Our sys admins are also well acquainted with deploying Django-based websites into OpenStack.

Although DjangoCMS has many advantages, it wasn't a perfect solution out of the box, and we had to make changes to make it work the way we needed. For example, the default text plugin will sanitize what you put in, so if you tried to add raw HTML outside of what the WYSIWYG supported, it would convert your tags < > into < > instead. Thankfully DjangoCMS supports adding custom plugins, and creating a RawHTML plugin type to use when we needed it didn't take much work. The CMS also required that we set some additional permissions for editor-level users, which weren’t set when they logged in from Ubuntu SSO, so we had to add some callbacks to django_openid_auth to grant those.

One thing we haven't overcome yet is the picture plugin's lack of resizing options, but that has only caused minor inconvenience so far. The admin interface, built on top of Django’s admin, also leaves a lot to be desired when it comes to usability, especially for those who are used to WordPress’s far more polished admin pages. But the inline page editing feature means that we don't have to go into the admin very often.

Getting high availability done right with DjangoCMS turned out to be far easier than we expected. We knew we would have multiple instances of it running on an OpenStack cloud, and so we would need them all to serve the same versions of media files. By default, Django stores both static files and uploaded media on the local filesystem, but that would mean an image uploaded for a page would only exist on one of the front-end instances. Luckily, Django has configurable back ends for file storage, and using django-swiftstorage as the backed let us use Swift, OpenStack’s distributed object storage service (similar to Amazon’s S3), for both static files and uploaded files. Best of all, both the DjangoCMS plugins and the Zinnia blog engine just worked with it, like magic.

After we put all of the pieces together, tweaked the configuration, and made a few code changes, DjangoCMS was a drop-in replacement for our previous WordPress system. The deployment and transition went off without any major problems, and we quickly were able to turn our eye toward expanding the functionality of the site with new, custom code. We’ve already added a webapp generator form, which builds ready-made app packages for the Ubuntu phone. More recently we merged the separate API documentation website back into the main site, which brings them back under one roof again, and, incidentally, made the API docs even more useful by taking advantage of the Swift storage for uploading embedded images.

DjangoCMS has proven to be just the right balance of simplicity, flexibility, and power. Being open source, highly configurable, and built on top of a well-designed platform made DjangoCMS easy for us to adopt and expand. DjangoCMS can be run locally for development, on a traditional server instance, or deployed at scale with OpenStack and Juju. Best of all, the whole site, including the parts specific to developer.ubuntu.com, are open source and available for community contributions.

The Open

CMS

This article is part of the The Open CMS column coordinated by Robin Muilwijk. Share your stories about working with open source content management systems (CMS) and platforms like Drupal, Joomla, Plone, WordPress, and more.