Matt Sweetman

New website built with Haggerston

The latest version of this site was built using Haggerston, a static site generator developed in Node.js by myself and Kelvin Luck. It was named after the place it was built in.

For the past few years this site has been powered by Wordpress, but after several hacking attempts and an endless battle with spam I decided it was time to change. The new site is served as flat HTML - no PHP or databases in sight. I write the articles in markdown, run Haggerston, then sync the files to the web server. It's fast, easy to update, and security issues are kept to a minimum.

Leveraging the power of Grunt

Haggerston is built as a Grunt task. The reason we chose Grunt is because it can already do a lot of what is needed to generate a static site. It can copy files and folders, compile CSS, rsync to remote hosts, start local servers, and watch for file changes. The only task that's missing is one to generate HTML pages. This is where Haggerston comes in.

Haggerston is a relatively simple task, it's job is to turn a folder of .json files into .html files. Each json file specifies a template to use when rendering the html. If you've used javascript templating libraries before then the process should be familiar to you. All Haggerston is doing is turning templates into html files, and using the json files as data for the templates. Haggerston uses Swig as its templating language.

A basic example

Using Haggerston is as simple as dropping in an empty task into your Grunfile.js:

module.exports = function(grunt) {
  grunt.initConfig({
    haggerston: {}
  });

  grunt.loadNpmTasks('grunt-haggerston');
};

This makes the following assumptions: source files exist in a subfolder called src/content, templates exist in src/templates, and the generated site will be created in a subfolder called out. Each of these properties can be overridden in the config if necessary.

Let's take the url for this article as an example. The page exists at /articles/new-website-built-with-haggerston/, which started life in a source folder on my local machine like so:

src
└─┬ content/
  ├─┬ articles/
  │ └─┬ new-website-built-with-haggerston/
  │   └── index.json
  └─┬ templates/
    └── article.html

Running grunt haggerston from the command line will take each .json file from the content folder, render it against a chosen Swig template from the templates folder and export the .html into a corresponding structure in the output folder:

out
└─┬ articles/
  └─┬ new-website-built-with-haggerston/
    └── index.html

You choose which template to render the data against by specifying it in each json file. Let's take a look at the index.json file of this page as an example:

{
  "template": "article.swig",
  "templateData": {
    "title": "New website built with Haggerston",
    "date": "2013-04-27",
    "blurb": "How I built my new website with Haggerston and Grunt",
    "content": "index.md"
  }
}
  • "template" specifies which Swig template will be used to render the .html file. This is the only mandatory property of a Haggerston .json file.
  • "templateData" is the data that will be sent to the Swig template when it's rendered. You can put anything you like inside it, or omit it entirely.

This process is extremely simple, but the key to making a good static site is knowing how to use templates. Swig supports something called template inheritance which allows templates to inherit and override blocks of markup from their parent. I won't go into detail here, but check out the Swig documentation for an example of how to use it.

Using the concept of middleware

Each step in the Haggerston process is designed as middleware, an idea borrowed from connect that allows developers to intercept the flow of a process and manipulate the data being worked upon.

You may have noticed a property in the index.json example above:

"content": "index.md"

Haggerston is designed to find properties with values that end in '.md'. Once it finds them it tries to locate the referenced markdown file, parse it into html, and replace the original property with the result. This means that when you use {{content}} in your template you're actually getting the html generated from the index.md file, not the string 'index.md'.

The part of Haggerston that does this is called the Markdown middleware. It's simply a function that gets called during the overall Haggerston Grunt task. Each middleware acts the same, and the function is given access to all the json data and rendered templates, meaning it can manipulate the pages in whatever way it likes before they're written to disk.

The basis for a piece of middleware looks like this:

module.exports = function() {
  return function (pages, next, options) {
    // Here you can manipulate the pages array in whatever way you want.
    // Afterwards just call next(pages) to continue with the Haggerston process.
    next(pages);
  };
};

Haggerston comes with a default set of middleware modules that performs common tasks. Each middleware is executed sequentially, and is top-and-tailed with core tasks that cannot be moved. Here's an example of how the overall process works:

  1. Core process: Read .json files into javascript objects
  2. Middleware: Read markdown files and parse them into html markup
  3. Middleware: Render the template into html markup
  4. Middleware: Highlight any code blocks found in the rendered markup
  5. Core process: Write the rendered markup to .html files.

You can write your own middleware and insert it at any point between the opening and closing core processes.

If you want to know more check out the github repo, or take a look at the source of this website.


Flashkana for iPhone

Flashkana screenshot

Flashkana is now available on the App Store for iPhone. This is the iOS version of my original Android app.

After finishing the Android version I spent some time trying to figure out the best way of porting the app to iOS. Eventually I decided to write it from scratch using the native toolset. I was keen on learning Objective-C and I knew using Cocoa-Touch for the UI would give me the best performance. I even found time to brush up on C while learning about pointers.

My late arrival to iOS development has given the framework plenty of time to mature. Building apps is quite an effortless process, the XCode toolset is rich and powerful, documentation is detailed, and community support is plentiful. It took a fraction of the time to develop compared to the Android version. It was obvious that the Android framework was still finding it's feet when I started. I remember I had to write a custom component to achieve the card-swiping mechanism. In iOS the UIScrollView gave me exactly what I needed, right out of the box, instantly solving a large chunk of the build. (It's worth noting the same type of component is now available in Android.)

The only slight hiccup was the certificate and provisioning process, which is a little byzantine (at least compared to Android and the Play store).

The app is free, so head over to the App Store to check it out.


What's That Tag?

What's That Tag? screenshot

What's That Tag? is a small game I've been working on recently. The aim is to guess what word has been used to tag a collection of images. The images have originally been tagged by users on Instagram and the game uses it's API to search and retrieve relevant photos. For each round it takes six images and shows them to you one-by-one till you correctly guess the tag that was used to conduct the original search. Bonus points are awarded for each un-shown image!

The game was built using Backbone, Underscore and jQuery. It uses CSS 3D transitions for the image flipping animation, so you'll need a modern browser in order to play it. It also works on iPad, although because the keyboard needs to be visible it's best played in portrait.

After testing it for a few days I've found the quality of tagging on Instagram pretty dubious, which can make the game quite difficult. I've adjusted the search terms to try and return more obvious images but it can still be pretty tricky. Perhaps another API like Flickr might be better.


Base class for Backbone

The core Backbone objects (Model, View, Collection and Router) have a convention for construction and initialization that make them feel more like traditional classes. This convention provides a degree of consistency across the Backbone framework. In a large project you might find yourself wanting to use it for all objects, not just Backbone ones, in which case the following snippet of code might help you out.

BaseClass ensures it follows several rules laid out in the other Backbone classes:

  • Call initialize upon instantiation, passing any arguments that were sent in the constructor
  • Extend prototype with Backbone Events functionality
  • Give each instantiated object a unique id

This is the minimum existing Backbone classes provide, so it's perfect as a basis for our class.

// Create a new constructor function and call initialize on instantiation
// This follows the convention laid out by other Backbone classes
Backbone.Class = function(options) {
  this.cid = _.uniqueId('class');
  this.initialize.apply(this, arguments);
};

// Extend the prototype with Events and a default initialize function
_.extend(Backbone.Class.prototype, Backbone.Events, {
  initialize: function(){}
});

// Add the extend method to allow us to create subclasses of the object
// Steal the reference from Model as it's inaccessible outside Backbone
Backbone.Class.extend = Backbone.Model.extend;

The only slight oddity is how we must borrow extend from one of other Backbone classes. In this case we've chosen Backbone.Model, but View, Router and Collection are equally valid. Unfortunately Backbone doesn't make the extend method available publicly so this is the only solution.

The base class can then be used in a similar way to other Backbone classes:

var LoaderUtility = Backbone.Class.extend({
  initialize: function(options) {
    this.timeout = options.timeout;
  }
});

var loaderUtility = new LoaderUtility({timeout: 5000});

You might find this adds a bit of consistency to your code base. If this approach is too reliant on inheritance then you can always try adapting the example to create a mixin.


Javascript 1K demo

Lattice of Love screenshot

Lattice of Love is my submission for this year's JS1K competition. The theme is 'love' so a heart seemed quite appropriate.

The lattice pattern is based on a hypotrochoid, better known to many kids as a Spirograph. Instead of rolling the cog around a circle I've rolled it around a heart shape, which is be described using the heart curve equation. I've used a couple of Canvas bitmap operations to provide a slight blur and after-image, which help smooth out the visual appearance.

The code was optimized and compressed using Google's Closure Compiler, which got it down to 813 bytes - nicely under the 1K limit.

You can check out the source code here: https://github.com/webroo/lattice-of-love