CMS Stress

The journey to Gin (part 1)

Wait...what? Where's the directory I was just..? Oh, shit. I didn't. I couldn't have.... Fuck. I did. OK. Think. Backups? I keep everything under version control but...not the content. Did I make a copy of the content directory as recommended? No. Why would I? I've performed hundreds—if not thousands—of similar operations and never lost anything. Until now.

Oh my word!

In December of 2015 I had an idea for a tool that would allow me to catalogue my favourite words. I knocked together a Chrome extension in an afternoon and was pleased with the return on investment. It was basic, but effective. About a month later, the extension supported multiple users and had an accompanying mobile app and a website.

The main site was actually a purpose-built Node application, and the blog was powered by Ghost.

OK, what else? Think. Cron job: automated backups of the DB. Crap. I didn't get around to setting that up. I was more concerned with the code. OK. How do you recover files deleted with rm? Maybe if that sector of the disk hasn't been overwritten, I can recover the directory I deleted...


John O'Nolans original concept for a lightweight Wordpress was inspiring and I was an immediate fan of the idea, as were many. The Ghost team ended up abandoning the idea of gutting wordpress and instead built a CMS from scratch, and I started using it as soon as the earliest version became available. It only had basic features; no multisite capability, and neither the dashboard that impressed everybody nor the plugin API were anywhere to be seen.

It has improved considerably since then, adding important features like multi-user support and post scheduling. But even back when its feature set was quite limited, I loved it. I was especially excited about what it would become. It felt refreshing, after spending so much time with Wordpress, to use a CMS that really felt like it was designed for writing. It was lighter, faster and less cluttered than the dreaded 'press.

Damn it. This is why I prefer the content to live outside of the application. Restoration would be easy... Fuck sake. How did I not get around to scheduling backups? Wait, I swear the pages get pre-rendered somewhere...


When I first discovered Wordpress, I'll admit, I was somewhat enamoured. At the time, I was coming from Joomla, and even though I was already a PHP developer by that point, I just couldn't get into it. Wordpress, however, was easy to get into. It had a user-friendly interface, a vast number of plugins and themes available, plenty of documentation and was incredibly easy to extend, if you had even a modicum of know-how. Even though it was originally just a blogging platform (wait, that's not the Wordpress tagline...), you could—and still can—build practically any kind of website with it: blogs, portfolios, e-commerce sites, web applications and APIs. All these things made it very popular and, as a result, I spent years working with WP, both professionally and in my spare time, but never more intensely than while working on the Rough Guides website. This was where I fell out of love with Wordpress.

Between dealing with the scores of active plugins (many of which had quite unhealthy code), a monsterous functions.php file, and the frequent code-dives into the WP core in order to figure out things like: why we have slow-loading admin pages, finding out when a cronjob has run and taming a racing heartbeat, it ended up feeling less like working and more like wrestling with Wordpress. When I finally ended up moving to another project, I was actually a little relieved; I didn't think I could be any more frustrated than I was with WP. And then I met Drupal.

This never would have happened with Wordpress. Database inside the application directory... Jeez. No DB backups. No content backups. Can't recover from disk. No cached static files. There has to be something else. There's always another way... Shit. Wayback Machine.

Drupal (7.x)

The project I'd been moved to was a trio of sites that used Drupal for content management. The public websites were SPAs (single page applications) that loaded content from JSON files exported from Drupal via a couple of NodeJS applications. This meant the CMS was never hit by ordinary public traffic, content could potentially be downloaded for offline consumption, and the server required to serve the content could be pretty lightweight, because all the data was static.

I liked the concept, but the implementation was questionable, to say the least. For instance, the publishing process took 1–2 hours which, in my opinion, is unacceptable and completely unnecessary, especially considering this architecture was designed for use within a publishing company. The NodeJS applications were a mess. Thousands of lines in a single file, spaghetti code and multiple pyramids of doom. Modularity and testability were foreign concepts.

Besides the things above that we could control, we also had to deal with those we couldn't, like Drupal's quirks and bugs "features" (like this one), and potentially useful plugins that appear to have been abandoned (like this one, at the time of writing its development status is "under active development", yet is still in "beta" and hasn't been updated since January of 2015). Plus, it often felt painfully slow. Above all else though, what really made Drupal challenging (and unpleasant) to work with was the documentation: occasionally non-existent, sometimes sparse and all too often poorly written. When I started using Drupal, I finally understood my predecessor's frustrations.

We ended up refactoring the project, and it was so time-consuming and stressful that all development on Oh My Word! stopped. This was quite inconvenient, since I had a massive error to rectify.


In September of 2016, I accidentally deleted the content directory of the Oh My Word! Ghost installation. The SQLite database that Ghost uses was gone. After various failed attempts to recover the data, I ended up writing a script to crawl Google's user-content web cache (as Wayback Machine hadn't recorded as much content), retrieve all the Oh My Word! pages and write them to a new directory. I then changed the server configuration to serve the static HTML files rather than hand requests over to the apps.

Even now, many images are still broken, because they were uploaded to the content directory I deleted. There is no CMS to manage the content. Neither Ghost nor the custom NodeJS application are running. The entire site is completely static. It was a mistake borne out of an uneven distribution of care and a tendency to value code over content. But, it provided a valuable lesson, and encouraged a different way of thinking about the relationship between code and content.