From WordPress to Jekyll

When I first started this blog in 2006 I built it using WordPress. It's a good, solid platform with a whole bunch of useful extensions, and it's not too difficult to get it set up quickly.

The last year or so though I started adding more to the front of the site, such as resources, guides and the personal development blog list. It wouldn't have been too difficult to build these in WordPress, but it wasn't something I was particularly interested in doing. Most of my freelance work involves WordPress, so perhaps after working with it all day that's why I wasn't too excited by it.

In the end I decided to try out Jekyll. It took a bit of getting used to, but it quickly grew on me. Not only is the site much, much faster now, but I find it easier to add new stuff without worrying about creating custom plugins or templates.

Site Speed - Before and After
Figure 1: See if you can guess when the site switched to Jekyll…

Although the speed of static pages is a huge plus, for me Jekyll's strongest feature is the custom post meta. Each file has a short YAML header, and any extra data can then be accessed in templates. This made it much easier to build the resources section, and as it's plaintext it doesn't take long to add new data.

Rebuilding the site

Of course, it wouldn't be me if I didn't try and do something far more complex than necessary. The standard Jekyll layout is pretty bare-bones, and I didn't really like how pages and posts were organized. I also wanted to be able to write my posts in org-mode, which meant I needed an extra build step to do all the conversion.

My current layout looks like this:

  • _staging - This is where site files are copied to before being processed by org and built by Jekyll. Also contains a cache directory to speed up rebuilds.
  • assets - Images, styles and Javascript goes here.
  • config - Contains jekyll, emacs and other configs required to build the site
  • content - All site content lives here.
    • comments
    • pages
    • posts
  • data - Data used when generating things goes here. Mostly the bits database.
  • plugins - Jekyll & Phing plugins live here
  • scripts - Bits generation scripts live here, along with other bits of code for generating the blog list.
  • templates - Any templates live here
    • bits
    • layouts
    • partials

I use phing to manage the build process, which goes something like this:

  • Copy assets, content and templates to the _staging directory
  • Use emacs to convert org-files to html
  • Copy files to the correct place (such as moving content/posts to _posts) and rename them for nicer permalinks
  • Build stylesheet using sass
  • Build using jekyll
  • Run some cleanup filters & insert analytics code

This all goes into _staging/_to_deploy, which is then deployed to the live site using rsync. There's certainly room for improvement, but so far it's been extremely quick.

Plugins

Like WordPress, Jekyll can be extended using plugins. Jekyll plugins can be used to generate additional pages from data (such as archives), or add new filters & tags to template system.

I used the following plugins (some with a little modification):

  • ancestors.rb - This adds support for accessing a page or post's ancestors. It's used to generate the breadcrumbs at the top.
  • archive_page.rb - A plugin I wrote to generate the archives page. The appearance is base on the "smart archives" plugin for WordPress.
  • category_generator.rb - Generates category pages. They're not quite as nice as WordPress's (no pagination), but they get the job done. After viewing my site stats it didn't seem worth adding "proper" category archives as virtually nobody uses them.
  • sitemap_generator.rb - Creates the sitemap used by the site.
  • static_comments.rb - Adds support for comments. Comments work in pretty much the same way as posts. Each post has a directory for comments, and each comment lives in its own file.

Problems

There were a couple of problems I ran into during the conversion:

  • I changed the permalink structure from "/blog/year/month/slug/" to just "/blog/slug/", which meant any links to old posts would no longer work.
  • Jekyll doesn't generate category or date archive pages by default, and the pages that are generated don't support pagination. Not a huge problem, but some of the most popular pages on the site were pages in the date archives.

Thankfully both of these were solvable with a little bit of nginx code:

Redirect permalinks

# Redirects old date-based slugs to just plain article
location ~ "^/blog/(\d{4})/(\d{2})/(.*)/?$" {
    return 301 /blog/$3;
}

Redirect date archives

# Redirect year archives to archives page
location ~ "^/blog/(\d{4})/?$" {
    return 301 /blog/archives/#archive-$1;
}

# Redirect month archives to archives page
location ~ "^/blog/(\d{4})/(\d{2})/?$" {
    return 301 /blog/archives/#archive-$1-$2;
}

The result

It's more complicated than it needs to be, but overall I'm pretty please with how the move went.

Originally site generation was quite slow (2-3 minutes), so now I cache all generated content so it only needs rebuilding if something changes. That took the build time to around 15 seconds, which is plenty quick enough for my needs.

The only issue I've had so far is the site has pretty much dropped off Google. It didn't get a huge amount of traffic before, but Google Webmaster shows it has gone from about daily search 1,000 impressions to under 50. I'm pretty sure it's due to the change in permalink structure, but I'm hoping things will get better in time.


New Emacs Guide - Emacs as a PHP Editor

I've updated the guides section with a new guide: How to set up Emacs as a PHP Editor. There are some bits I'd like to add, such as how to manage PHP projects, but it still contains some good information. I also added some new Emacs snippets to the source code section of the site.

Whilst writing the guide I came across some new extensions I really like (such as web-mode), so I've also updated the Emacs Extensions Guide.


New Guide - Distraction Blockers

I've updated the guides section with a new resource: a guide to "distraction blockers". It's a collection of useful software for blocking distracting websites and applications.

You can view the guide here: Distraction Blockers


A simple Jekyll archives plugin

When I switched this blog from WordPress to Jekyll I ended up writing a bunch of Jekyll plugins to make the transition easier. I've updated the code section with the first plugin - jekyll-archive-page.

One thing I missed from WordPress was a nice archive page, so I wrote a simple plugin to build an archive page (the archive page for this site uses it). I based the output the "Smart Archives Reloaded" plugin for WordPress, although I don't use any Javascript.

It's nothing too fancy, and the code isn't very elegant, but it gets the job done.


How I Get Things Done

I currently work as a freelance software engineer. Although my work hasn't changed too much since I started, how I organise myself has.

This is a short post about how I currently get things done & my current work setup. I've always found it interesting to see how other people work, but I always want to be able to look back and see how my setup has changed over time.

Work

My tasks generally fall into the following buckets:

  • Working on stuff I already know about - This is anything that takes longer than a few hours. Most of my work falls into this category.
  • Working on new tasks - New tasks either come directly via email, or from support tickets
  • Phone calls - I try to keep these to a minimum
  • Fixing things - Finding out what broke, why it broke, and then fixing it

As work comes in I'll have to make a decision on how important it is, based on what it is and what I'm already doing. For example, if I'm working on a fix for one project and an email about tweaking text comes in, I'll put it off until I'm done. However, if a site is down or something is seriously broken I'll drop what I'm doing to fix it.

Daily Routine

I've kept this for the last few years. There's room for improvement, but so far I've found it to be the most efficient system for me.

  • Get up nice and early - I aim for 5:30am
  • Check for any important emails that came in overnight. Add anything else to my todo lists.
  • Work on whatever I have going on. Getting up early allows me to get important work done before everyone else wakes up and starts adding more.

    I'll check my org-agenda first to see what's due, and then work on any other priority items. I prefer to work on something that I can get done before 8 so that I've started my day in a good way.

  • Break around 8am for breakfast. I'll usually have a snack around 10am - either fruit or nuts of some kind.
  • Break at 12 for lunch
  • Aim to finish work for 5pm. Usually finish much later…

Every day is a little different. Sometimes everything goes smoothly and I have a nice, efficient day. Other times everything starts going wrong and my plan goes straight out the window.

Organisational Tools

I've simplified my setup in recent years, and it currently has very few components:

  • Emacs + org-mode - For things I need to think about harder I'll use some paper to sketch out notes, but that's pretty much it.

    I have a directory for client projects, and each client has their own org file. I also have directories for my own projects, and an inbox.org file for keeping track of incoming items and things that don't really belong anywhere else.

    All my org files are synced using DropBox.

  • Mozilla Thunderbird for managing my email
  • Trac for ticket management

Doing the work

The majority of my projects are web-based, so my setup is tailored towards making that more efficient. Like my organisation system, I've tried to keep things simple.

  • My editor of choice is emacs - see my list of emacs extensions for an idea of what I have installed. My .emacs.d is also synced using DropBox so that whether I'm on my laptop or desktop I have pretty much the same environment.

    I also use emacs for tracking my time, although for some clients I use Harvest.

  • All the sites I have in development are run from a single server. As my work is web-based it helps to have a local machine to test on, and it also makes life much easier when using different development machines.
  • PHP development tools include phpunit and behat for testing, and phing for automating things (such as testing and deployment). Everything lives in source control where possible. I prefer git as it's easier to get small repositories setup quickly.

    I also use guard and guard-livereload to refresh sites as I'm building them. guard alone has saved me hours when slicing things up.

  • Hardware consists of a dual-monitor GNU/Linux desktop and a MacBook Pro. I usually work on the desktop when I need more room to see things, such as turning an image into an HTML template.

Keeping Going

I use a couple of other tools to keep me in line:

  • RescueTime - This helps me keep an eye on how much time I'm spending on various activities. It also has a nifty tools for blocking websites when you need to focus.
  • Tomato.es - my favourite Pomodoro app at the moment, mainly because it's so simple and keeps track of statistics between machines.
  • Router block - All distracting websites are blocked by my router between 5am - 5pm. This gets rid of the temptation to "just check the news for a bit".
  • Beeminder - I have a private goal for tracking how much work I'm billing. At some point I want to add another goal to make sure I don't do any work past a certain time. It's all too easy to spend all your time working.