How I converted my WordPress blog to static HTML

I was tired of using WordPress for such a simple blog site. I wanted to write my posts in Markdown and I was using a Markdown wordpress plugin. But, something still didn't feel right. I didn't need this huge PHP CMS, and I didn't want to deal with the annoyance of updating and maintaining it.

So, I decided I wanted to re-build it as a static html site using a static html site generator, and I wanted to use Nodejs to run it. After lots of searching around and researching several options, I came up with a few I was considering.

  • Blacksmith - Made by the great guys at Nodejitsu.
  • Wintersmith - Flexible, minimal and has plugin options.
  • DocPad - Probably the most well-known.

I dismissed DocPad fairly quickly. It was just too big and did too much. I also got lazy and didn't want to read through the docs. Blacksmith looked really good. However, I had trouble running it at first, and again, I got lazy reading the docs.

I ended up choosing Wintersmith. This one is actually similar to Blacksmith, but it doesn't use Nodejitsu's flatiron and plates libraries, which I liked. I also really appreciated that it had the option to scaffold a blog site for me so I was up and running in a couple of minutes.

Installing Wintersmith

First thing you need to do is install Wintersmith in your global node modules so you can run the cli from anywhere. This assumes you already have Node and Npm installed (of course you do!).

npm install wintersmith -g

Now we have wintersmith installed, we can scaffold a project. We use the new command. Navigate to the folder where you want your project to live.

wintersmith new --template [name]

It has three different options basic, blog, and webapp. Of course, I chose blog. BTW, It defaults to blog if you don't specify a template. You can now immediately test out your site by running wintersmith preview. Go to http://localhost:8080 to see it!

That's it! You are up and running with Wintersmith. That was easy.

Configure Wintersmith

You have a working site, but now you need to configure and customize it. One thing I didn't really like was that Wintersmith uses Jade templates by default out of the box. I am not a fan of having to learn a completely different syntax to write in something else. Luckily, there are several plugins to choose from that let you use other templating libraries.

In the end, I got lazy and just stuck with Jade (I know right!). I liked the default blog template, and I just tweaked mine here and there. I really like how it turned out. It's super clean, minimal and fully-responsive with minimal CSS and NO JS! (ok, only a tiny js file for the search page, which we will get to soon enough).

The first thing we need to do is open the config.json file in the root folder. This contains the necessary options for your website. The default looks like this:

{
    "locals": {
        "url": "http://localhost:8080",
        "name": "The Wintersmith's blog",
        "owner": "Someone",
        "description": "Ramblings of an immor(t)al demigod"
    },
    "plugins": [
        "./plugins/paginator.coffee"
    ],
    "require": {
        "moment": "moment",
        "_": "underscore",
        "typogr": "typogr"
    },
    "jade": {
        "pretty": true
    },
    "markdown": {
        "smartLists": true,
        "smartypants": true
    },
    "paginator": {
        "perPage": 3
    }
}

The locals section is the most important for your site. Update these for your specific site. The plugins section lets you specify plugins you want your site to use. You can get details for each plugin from the plugins page. The require section lets you use node modules in your template files to do custom logic. The jade section is only if you are going to use Jade templates. Each template plugin has their own options. Markdown section lets you specify options for that node module, and paginator lets you specify options for the paginator plugin that is installed by default in the plugins folder.

The locals section is very convenient. Anything in here is automatically made available to you within your templates. You can add any custom members you may want to access. Note that every template receives the locals object. I will get to page specific data soon.

Adding and editing your content

Now take a look in the contents folder. This is where all of your site data lives, and what will actually be built and deployed to your host environment. You can add any js here as well. The articles folder contains your actual posts. Notice that every folder contains an index.md file. This is a markdown file of that particular post. It's named index, because it gets built into an index.html file and that keeps the url structure of your site looking clean.

Wintersmith also comes with an already made feed page for RSS feeds, and an archive page. Very nice!

Let's look at a typical index.md file. You may notice this at the top of the file:

---
title: Taketori Monogatari
author: Princess Kaguya
date: 2012-02-01
template: article.jade
---

This is the metadata for this post. You will be able to use this data in your templates to build dynamic post pages.

There is only one required field and that is the template field. This tells Wintersmith which template file to use when rendering this page. If left blank, or set to none the page will not be built.

This is where you can add any custom fields of data you may want to access in your templates. I added a tags field which is a comma separated list of tags, and a disqus field. This is a sort of canonical slug of each post. I use this to use Disqus comments in my posts (scroll down and post a comment!).

Customizing your templates

Let's move on to the templates folder. This will contain several pre-built Jade templates with a .jade file extension. You will want to study these to get a feel for what data is available in your templates. Each template engine has it's own syntax and way to access this data.

You can access the locals data anywhere by using the locals object.

In the index.jade template, there is a loop that renders the most recent posts on your site. Here is a snippet of code where I render my tags using the article's metadata:

- var tagsarray = _.toArray(article.metadata.tags.split(','))
      ul.tags
      each tag in tagsarray
        li.tag= tag

Oh yea, did I mention it has UnderscoreJs running already? That's convenient. You can see, I accessed the tags field I added to my posts by calling article.metadata.tags. Then I split them by the comma and render them in an unordered list. Works great.

Adding Disqus comments to your posts

Since I am building a blog site. I wanted comments on it. You are pretty limited here since there is no server behind your blog which you can use to manage your comments. Luckily there are nice services like Disqus.

I added a comments div at the bottom of my article.jade template. I also access the disqus field in my article's metadata.

if page.metadata.disqus
    div.comments
        h3 Comments
        div#disqus_thread
            script.
                var disqus_identifier = '#{page.metadata.disqus}';
                var disqus_shortname = 'lovesmesomecode';
                (function() {
                    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
                    dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
                    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
                })();
            a(href='http://disqus.com',class='dsq-brlink') comments powered by Disqus

This is just the html embed code I got from Disqus, converted into Jade syntax. I used a conditional to only render this if my article has the disqus metadata field. Then I passed this field into the disqus_identifier. Very simple. I got comments on my blog!

I also added a comment count to the index page for my articles list.

div.comment_count
  a(href=locals.url + '/post/' + article.metadata.disqus + '#disqus_thread') 0 Comments

By adding the hashtag #disqus_thread to any link, their code will automatically populate this with the number of comments for that post. Just be sure to add the script code you get from Disqus to the bottom of your page.

Building your site

Now that your site is all ready to go, the only thing left to do is build it.

wintersmith build

That's it!?

That's it. This will generate a new folder called build, and it will contain all of your deployable content. Html files, css and js files, and anything else you added to your contents folder.

Oh yea, I hope you have been leaving wintersmith preview running. This let's you constantly view your site while you are working on it. You don't need to restart it when you update any of the files in your site, including templates and config files. It just works, and it's really nice.

Summary

I think that's enough for now. This should give you a good head start to converting your blogs to static sites. By the way, I am hosting my new blog for free on Github Pages. Nothing beats free!

You may have noticed I have a search box at the top of my page. I used a nice free service called Tapirgo. I will write up another post with a walk-through of how I did this. It was really easy, and needed very little javascript to make it work.