Content management, markup and doing it wrong

A few days ago I put out a poorly worded tweet about my feelings towards content management systems that leave traces of their own HTML in the frontend markup of the sites that they power. I said:

If I can tell what CMS you are using by looking at your markup, you are doing it wrong.

Of course, my emphasis here was all wrong - it sounded like I was putting blame at the feet of the user, rather than the CMS, which is not at all what I intended. After getting a few questioning responses, I tweeted a clarification:

To clarify: If I can tell what CMS you are using from looking at your markup, *your CMS* is doing it wrong.

What am I talking about here? In my mind — and in vastly oversimplified terms — a CMS should exist to provide a nice way to store structured data, map URLs to some kind of template/page and give you access to the data stored within it via some sort of templating language.

It is definitely not the job of the CMS to wrap that data in it’s own markup. How can it be? It can’t know ahead of time how I want my markup structured. It doesn’t know the template context that I’ll be using that data in, or how I like to write my markup. It doesn’t know wether I want to use double quoted attribute values, or if I want to add microformats when I output it, or whether I’ve decided to use an OOP-style CSS strategy (and it’s accompanying bevy of classnames) for my project.

So let’s step back a little and look at the different ways that a CMS can include markup in their output. I’ve started by lumping them all together, but that is a little unfair - some CMSs do this in ways that are far more toxic than others.

Starting at what I see as the optimum end of the spectrum we have content management systems that quite literally provide you with a blank slate - no default templates, no default markup. ExpressionEngine is a good example of this kind of CMS. It gives the developer a templating language powerful enough to extract content from it’s structured data store (the structure having previously been defined by the user) and you have complete control over what markup you choose to wrap around the discrete chunks of content. It has a powerful plugin architecture, but instead of these plugins providing direct HTML output, they typically just extend the templating language to give you extra tags to work with, so you can once again use your own markup to display the content with.

Then we have systems like Wordpress, whose templating language similarly attempts to provide you with access to the discrete items of data within it’s database. However, this templating API often returns content ready wrapped in HTML, such as when retrieving a list of categories or pages. Thankfully you can often customise this markup by passing extra variables into the function that is being used to retrieve the data, but this still feels inelegant to me - why jump through all these hoops when you could just give me back the data and a standard way to iterate over it and then I could build my own markup around it?

A perhaps bigger issue is that because the Wordpress core has set the expectation that generating output in this way is a good way to do things, plugin makers have followed this convention, but often with less regard than the core dev team for providing ways to override the default HTML output that they produce. So by using these plugins you are relying on the (often pretty shaky) frontend development expertise of the plugin developer to craft your markup for you. Not ideal.

And then towards the other end of the spectrum we have systems such as Drupal, which output large swathes of HTML by default, and often with little or no regard for correct use of semantics or for giving the developer the ability to override the markup with their own, or even customise small parts of it, such as the class names used. Each third party plugin typically brings it’s own large chunk of HTML output with it, which often reflect the plugin authors own style of writing HTML and which rarely (if ever) meshes seamlessly with the other generated output that is sits within.

Now, don’t get me wrong. I do think there is a place for content management systems that come with pre-packaged templates, such as Wordpress with it’s default themes. Obviously there will always be a large number of non-tech savvy people who want to set up a blog and don’t want to have to learn a bunch of markup to do so. But the templates should be just that, templates - and they should be directly editable as such. No one should have to go passing umpteen arguments into a function to customise the classnames attached to their unordered lists.

And, perhaps more controversially, I think that professional frontend web developers, those who really understand the difference between good and excellent frontend development, should steer away from these content management systems (or else be prepared to spend hours digging around in their internals to wrangle the markup to fit their own standard and style).

Yes, generated markup can save you time. But you can easily create a library of reuse-able template components for a CMS like ExpressionEngine that give the same time saving benefits but which is written in your own style, and more importantly can be easily customised to fit specific use cases - adding microformats, removing superfluous class names, or single quoting those attribute values… should you feel like it.

In short, I think that markup is too important to be left in the hands of the people who make content management systems. They all too often don’t care enough about it, and they can never know the context that you will be using it in, and so in my opinion they shouldn’t be trying to guess.

jQuery URL Parser v2.0

I finally found some time to rewrite my jQuery URL parser plugin over the last couple of days. The new version (v2.0) is up on Github now, and is pretty much a ground-up rewrite so should be much nicer to work with.

It’s got a much nicer and more consistent API now, and has some added functionality over the first version, including being able to get parameter values and/or segments from the fragment (anchor) part of the URL.

The docs should explain it all in more detail - any bug reports, queries or feature requests please add to the project’s Github issue queue. And please note that this new version is not backwards compatible with the 1.x branch!

jQuery URL Parser on Github

ExpressionEngine, Structure and 404s

A little tip for anyone that uses Structure with their ExpressionEngine installs: If you want your 404 error handling to work correctly, do not use template group names that are the same as top level URL segments. For example, if you are using Structure to create a listing page with the URL /news/, so that you are serving news items at URLs like /news/my-news-item, then don’t create a template group called ‘news’ to hold your news listing and news item templates.

If you do, then you are very likely to encounter some pretty funky handling of what should be 404 errors.

Um… Why?

Well, continuing with the news example above, when anyone tries to visit a news item that doesn’t exist - for whatever reason - the following will happen (lets assume the incorrect URL is /news/i-dont-exist):

  1. ExpressionEngine will try and find the news item that matches the URL that you have specified.
  2. When it can’t find the entry, it will fall back to the ‘traditional’ EE way of trying to serve up content, based on template_group/template pattern matching. Thus it will look for the template group news and a template called i-dont-exist.
  3. If there is no template with the name i-dont-exist, but there is a template group called news, then EE will happily go along and serve up the index template from that template group, rather than serving up your specified 404 template (which would probably be the desired result in this case).
  4. If you are using a dynamic exp:channel:entries tag in your template to pull in the page content and have not specified a channel using the channel parameter, then it will be populated with the contents of the latest entry added to EE. Even worse, if you unfortunately haven’t got a limit clause on that tag, it will actually try render the template once for every matching entry in your site! This makes a hell of a mess, as you might well imagine.

Why does this happen?

Structure works by hijacking the usual EE template_group/template URL routing scheme, and instead routes URLs to specific entries and then renders them using the template defined for that particular entry. However it doesn’t replace the usual routing scheme - it merely first checks to see if it can match a specific URL to an entry and then hands over to the normal EE method of handling URLs if it can’t resolve matters itself.

EE does have 404 error handling, but as the user guide states:

It is important to note that there are limitations when it comes to what will trigger this “404” type Template to display. ExpressionEngine will only display the 404 Template if the requested Template Group in the URL does not exist.

So if you have a valid template group name as the first segment of your URL, the 404 template will never be shown, no matter what else preceeds it in the URL.

How do I avoid this?

The easy way to avoid this is to make sure that your template group names never match any top level URL segments in your site. If you are letting clients create their own top level pages, then the best solution is probably to prefix your template group names with something to make this kind of namespace clash much more unlikely.

An alternative solution that was pointed out by John Faulds on Twitter, would be to not worry about your template group names but instead, in the group’s index page use the {no_results} tag within page primary channel entries pair to do a conditional redirect to your 404 template. This will work (providing you have set the require_entry parameter to ‘yes’ in the pages’ exp:channel:entries tag) but feels a little inelegant to me - I think that 404 handling shouldn’t really be implemented in templates, but rather in the system itself. However it may be a better fix if you already have template groups set up and don’t want to change their names.

A footnote on the Pages module

I’m 99% sure - but haven’t tested yet - that this same issue will probably occur when using the Pages module to specify URLs for specific entries, although you are probably less likely to run into or notice it. I believe that Structure really just hooks into the page-handling capability of EE to provide a nice interface to manage the creation of these ‘page URLs’, so this will probably suffer from the same issue.

It should be about people, not channels

Social networking is failing me.

I use Twitter everyday. I love it dearly, and it has allowed me to get to know a lot of cool people that I would (in all likeliness) have never come across without it.

But the majority of my ‘in real life’ friends – the people I grew up with, the people I went to uni with – don’t use Twitter. Most of them are pretty active on Facebook – but Facebook really isn’t my thing. I can’t deal with the noise.

So I find myself in a situation where, thanks to a social networking tool mis-match between myself and my closest friends, I know nothing about what they are up to every day, and everything about the lives of people who I have never met. Seems a bit odd, doesn’t it?

Because even though social networking feels people-centric while we’re interacting with it, in reality it is channel-centric. You can only be friends with your friends if they play in the same channel as you. Even if you and your friends all spend the hours of the day on the internet, if you are not using the same tools you can pass each other by like two ships in the night.

In my mind this is really the main problem that the next generation of ‘social networking’ tools need to solve. The emphasis needs to move away from the tools and onto the people - so I can keep up with my ‘IRL’ friends just as well as I can my digital acquaintances, without having to chain myself to a dozen social networking tools that i really have no interest in, just to cover all my bases.

jQuery Event-Driven Pagination plugin

I have just released a replacement for my Quick Paginate jQuery plugin – it has similar functionality but uses a custom event-driven API for much more flexibility. It’s been re-thought and re-written from the ground up, and although the documentation is still a bit lacking there is a basic demo that should help to get you started.

Check out the plugin on GitHub