PHP CMSes done right: how to enable clients to edit content appropriately
In the previous post, I talked about how CMSes harm websites. I debunked the oft used selling points of faster, cheaper and client empowerment over websites and explained how CMSes butcher semantic markup, code decoupling, tasteful style, speed optimisations, maintenance ease and code freedom.
Now I want to mention a few ways how a CMS can be appropriately used to build a website. There are two scenarios I want to cover: using pre-built scripts and prioritising custom code first.
By pre-built, I mean all you really want is an off-the-shelf setup and don’t care for customisations. So grab an out-of-the-box CMS (Joomla, Drupal, WordPress, etc), install an associated theme and several modules from the CMS’s ecosystem and glue them together. With this sort of set-up, you could have yourself a complex website system such as an e-commerce or blog site running within a day, looking good, and costing zilch if you have the know-how.
In this scenario, a CMS should be your top choice. The benefit of speed and set-up far outweighs the extremely costly alternative of custom coding such a complex system. It is for this reason that thinkMoult runs on WordPress: I just wanted a blog to run on the side with minimal fuss.
As the complexity of the system grows this benefit also grows. It would be rare to recommend to the average client to build a blog from scratch, an ecommerce system, a forum, or even ticketing system.
However once you plan on doing lots of customisations, you’re stuck.
Did that really solve anything?
Not yet, we’ve simply outlined a scenario where the cost benefit far outweighs the effort required to invest in a custom product. Unfortunately, all the issues still exist.
So how do we build a CMS for products which don’t fit those requirements – either small tailored “static poster” where first impressions are key or customised systems?
Sceptics might question why building a CMS now is any different from the CMS giants of the past. My answer is that the PHP ecosystem is maturing and the industry is standardising (see PSR-0, Composer, and latest PHP changelogs). Previously we relied mainly on CMSes as they defined a set of conventions we could live with, but now we have proper ones industry wide.
Place custom code first!
The answer is simple. The CMS should not govern your code! Markup style generating, logic modifying systems should be at least completely decoupled if not thrown away completely. The trick to do this quickly is to isolate exactly what a CMS needs to do: and that is to allow the client to edit content.
That’s right: edit content. Not glue modules, not define routing, not to restyle the page, and never, ever, to touch anything to do with logic.
If they ever need anything more complex than editing content, make a module for it. Make that custom module on top of your existing code, and link it to a config repository – nothing else. All it should do is flick switches, not act as a heavyweight crane.
Now, for editing content – I have five strategies to fix the “butchering” aspect of CMSes:
Start by ensuring your frontend code is completely decoupled from all logic. I like to do this by using Mustache as a templating language. It’s simple by design. If your frontend developers can’t break the site’s logic, your client can’t either.
Write your markup and styles perfectly. Writing perfect markup and styles means your editor won’t have to care about whether that extra <div id=”does_things” class=”active wrapper_l12″> was actually vital to the page operating properly. Everything is simple and only uses standard markup tags.
Use a semantic editor. A semantic editor preserves the goodness of point 2. I use WYMEditor, which has bee around for a while. Not only does it stick to the basic tags, it reads extra styles from documented CSS. This way you won’t have clients with no taste inventing new styles and layouts, but only using what you’ve provided.
Beautify the code! PHP Tidy is built-in and can produce well indented, cleanly styled code markup. Don’t have faith in automatic beautifiers? With your perfect markup and complete style/markup separation in points 2 and 3, all your beautifier deals with is the most basic of markup – which probably only needs indenting before it’s called classy code (no pun intended)!
Whitelist editable elements, not blacklist. The default state for whether content should be editable should be off. Don’t give them more than they ask. Because otherwise they will touch it, and inevitably break it. This means you’re custom isolating segments of editable content for the client (I move it into a Mustache partial), and testing it before handing the baton to the client. It also means you can monitor it much more easily- such as inserting an update notifier so that you can run
git diffand verify they didn’t somehow still bork things over due to Murphy’s Law.
Et voila! Your client now can edit the content, not break the logic, keep it semantic, keep the code beautiful, and only touches what we wants. He also has a series of switches for the more complex areas of the site. You’re also keeping watch via that update notifier I mentioned (with a monthly fee, of course).
What did we lose? Upfront development speed. What did we gain? Everything.
Note: the picture of the CMS is from a custom solution I developed for Omni Studios. Underneath it’s powered by Mustache, PHP Tidy, and WYMEditor, and good markup/styles, all mentioned in this post. So by custom, I mean rebranding a series of industry tools.