Wellfire Interactive // Expertise for established Django SaaS applications

Add Django content management to SaaS and other non-CMS sites (This Old Pony #38)

Here’s the scenario: you have an existing Django website, let’s say a social networking site to match prospective students and colleges with special programs. It works really well but you find that you keep needing to update copy on the site. Sometimes its the footer, or the about page, and other times it’s blocks of content in structured application-based pages (like college profiles). How do you make this copy editable from within the existing application so that you don’t need to redeploy for each copy change?
 

Flatpages

I remember working with flatpages in an early version of Django and thinking how neat it was that you could add arbitrary HTML pages alongside a CMS or structured data. And then I didn’t touch it for years.

However Django’s flatpages module[0] is incredibly useful for these scenarios, either directly or as a “template” to copy. Flatpages will let you define not only arbitrary HTML content in a page using predefined templates, you can do so with arbitrary paths to allow for a flexible URL structure (though be wary of how you exercise this).

Flatpages are a good option for pages like the “About” page and ToS and privacy policy pages, to name a few. A good idea is to add a data migration here with the initial content so you don’t deploy with a content hole.
 

Content blocks

Content across pages or inline in a page rendered by an app within your site is fair game for editing, too. This includes content like footers, subheadlines, welcome messages, etc.

We originally addressed this with a package of our own, django-addendum[1]. This uses _named snippets _to add template tags to any template, that is, any page. This lets you add editable content to pages rendered by views in third-party apps, too.

The main drawback of this particular solution is one of its main virtues: it’s insanely simple. Relying on the cache framework, it renders whatever text you entered in a plain Django admin text box. While it optionally allows markup (to be added un-escaped to the template) there is by design no WYSIWYG editor. 

If you need richer content editing, you might take a look at the “Content Blocks” grid over at Django Packages[2].
 

A full CMS

Adding a full CMS as your content management solution is a totally reasonable and workable option. If you’re already looking at some of the richer, more complex content block options, it makes sense to start weighing whether using an _actual content management system _is the best answer.

Take Django CMS[3], for example. Sure, it’s primarily designed for managing sites with large page trees and complex content models. However with its middleware based support for content blocks you can serve content from pages not in the CMS page tree. This means you can use it to control footers, snippets, and other content blocks. 
 

When to use what, and one more option

For a content heavy site, I’d give serious consideration to using a CMS like Django CMS or Wagtail[4] as the option for both separate content pages and content blocks in app-served pages.

For a SaaS or SaaS-like site start as lean as possible. Most of the content is pretty dynamic and user centric, so you shouldn’t need to be editing too much copy with much frequency. Instead stick to something like snippet editing and flatpages.

One problem some of these solutions pose is that they add overhead to integration testing. You may find you need to perform more setup because loading a view entails loading [possibly missing] data for the CMS, for example.

Which is a nice segue to the last option: make this content editable by rendering the customized content client side. There are various reasons for and against this strategy, but it doesn’t impact standard testing and it gives you exceptional flexibility. By coupling whatever arbitrary models you want with an API endpoint and client side JavaScript, you can load changes on the fly without changing what’s served by the Django application. 

Why would you do this? The main reasons have little to do with technical integration. If part of your strategy is service user customized content or A/B testing on any kind of copy in your app[5] this is probably a better way to go.

<strong>Cheers</strong>
Ben

[0] https://docs.djangoproject.com/en/2.0/ref/contrib/flatpages/
[1] https://github.com/bennylope/django-addendum
[2] https://djangopackages.org/grids/g/content-blocks/
[3] Django CMS
[4] Wagtail
[5] Alternatively you might rely on a dedicated A/B testing service, e.g. VWO or Optimizely

Learn from more articles like this how to make the most out of your existing Django site.