Rich text fields and faster horses

12 March 2015

All too often, content management is a compromise between structured information and offering flexibility to editors. The next release of Wagtail brings a new feature that offers the best of both worlds.

One of the fundamental design decisions we made when we first built Wagtail was to give editors a structured, "fill in the blanks" interface for entering content. Suppose you're creating a page about an event; you'll be given a ready-made template with fields for the event name, location, start and end dates, event description and so on. Where it makes sense to have a set of similar items - such as a list of speaker profiles, or images for a carousel - you have the ability to create as many of those items as you like, but that's the limit of the flexibility we give to you as an editor.

This doesn't give editors much opportunity to show off their creative flair, but what they do get is a much simpler learning curve. They don't need to learn how to format their page to make it look good, or follow a style guide to make it consistent with the rest of the site - that's handled by the site developer. This separation of responsibilities is the heart of what content management is all about, and it's possible because we're capturing the semantic value of what the editor provides.

By "semantic value", I mean that we are recording information about what the page content means, not just its styling: essentially, the data we store should be as close as possible to the information the editor has in their head. In other words: "this event is on the 14th of May", not "there is a second-level heading here saying Thursday 14th May 2014" (or worse: "there is some left-justified text in 16-point Helvetica Neue here saying Thursday 14th May 2014"). That way, if we suddenly decide that all our dates should be displayed as third-level headings in American mm/dd/yy format (goodness knows why), or want to produce a list of upcoming events, we have the information to do that.

In practice, most of the time we can't be so purist about the data we collect - editors want to be able to create freeform content, mixing text and images in a way that doesn't fit our pre-determined templates. Up to now, our stock answer has been to make the 'event description' field a rich text area - this provides the editor with a friendly WYSIWYG editor where they can liven up their text with subheadings, bold and italic formatting, links, images and even embedded video. Ever since Wagtail launched, developers have been clamouring for the ability to add more types of content to the rich text field: pull quotes, tables, email links, code snippets, Google maps. Wagtail does support extending the rich text editor in this way, as detailed in this blog post from Joss Ingram - but it's not something that we officially encourage, and I've stubbornly refused to make any of those additions within Wagtail itself. As a famous Henry Ford quote goes:

"If I'd asked my customers what they wanted, they would have asked for faster horses."

Henry Ford wasn't in the content management business (nor did he actually say those words, but bear with me here) - but if he was, he would probably have felt the same way about rich text areas. Richer rich text boxes are like faster horses: they seem like a good thing to have, based on what you're familiar with, but they're not the real solution to the problem.

For a start, browser-based WYSIWYG editors are simply not very good. That's not a criticism of the people who create them, just a consequence of how they work. For Wagtail, we chose hallo.js as our WYSIWYG component, but all the available libraries boil down to the same thing: a wrapper around contentEditable, a browser feature that turns part of an HTML page into an editable region with a cursor and the ability to insert, delete, copy and paste. If there are any quirks in how the browser implements this, there's not much the library can do to fix them. And once you go beyond basic text formatting, those quirks come thick and fast: things like being unable to put your cursor on the far side of a floating image to delete it, or unwanted font styles cropping up when you paste text from Word. The situation will only get worse as you introduce more complex elements such as tables.

More importantly, though, we're losing the semantic value of the content. If you want to insert a Google map on your page, you can get a blob of HTML from Google, and (with a bit of jumping through hoops) you could persuade Wagtail to insert that HTML into a rich text area. But the actual meaningful information - "a map centred on the postcode OX7 3EW" - is buried irretrievably within that blob of HTML. If, later on, you want to switch to OpenStreetMap as your mapping provider of choice, or repurpose the information for an "events near you" listing, you're back to square one.

Once you rely on a rich text field for these things, you're arguably giving up on content management entirely - the content of the field is unknown "here be dragons" territory. So how do we give editors the flexibility to create this freeform content, without losing our handle on the semantic value of what they're entering?

Our solution, coming in the next release of Wagtail, is StreamField. Inspired by projects like Made By Many's Sir Trevor, we treat the page content as a sequence of blocks of differing types to be rearranged as desired - headings, paragraphs, images, block quotes and anything else you can imagine. By handling these block types as equal citizens, rather than shoehorning them into an interface designed primarily for text, we can make the editing controls for each one as simple or as complex as needed: that Google map block could be a simple postcode field, or a drag-and-zoom location picker.

Once you've got yourself out of the rich text area mindset, you'll find better ways of organising and presenting information. You wanted to insert code snippets on your programming blog? Let's create a new block type for that, complete with line numbers and syntax highlighting. You wanted to include a table in the page? How about a spreadsheet-style editor - or if there's something else that's better suited for the data you're entering, we can handle that too. Email links? Chances are, you're creating a "contact us" page, so let's create a reusable "Contact" block type with email, telephone and anything else we think is relevant - then we can make it downloadable as a vCard, or maybe collect all of our Contact blocks into an address book.

We think StreamField is going to open up all kinds of new possibilities, just like... well, trading your horse in for a brand new Ford Model T. We can't wait to see where you take it.