Migrating this site to Hugo

Last modified 2022/09/20 20:34

Today I migrated this blog from Sculpin to Hugo.

I created the site originally in 2018 using the wonderful, PHP based, Sculpin static site generator. It has proved to be a good decision, previously my personal homepages used a database and anything I wrote on them is lost to history (a mournful loss to posterity), now all of my blog posts are on github, and I can author them locally in my favourite editor.

But over the years it has become slower to compile, I have 138 blog posts (mostly for cycle touring) and it can take up to a minute to build the site, especially on my not-very-powerful server.

Hugo is a Go based static site generator, which promises to be much faster so I thought I’d try switching as I had nothing else to do today.

Installing Hugo

I was sceptical about installing the Hugo binary - at least with Sculpin I could do a composer install and know that the version of Sculpin I install would be compatible, where as with a binary there is no constraint.

It was however as simple as apt-get install hugo both locally (on the latest Ubuntu) and on my server.

Content

Adding content to Hugo was very easy as most of my blog posts are pure markdown. It was as simple as:

cp ../oldblog/source/posts/* content/posts/

and similar for my assets:

cp ../oldblog/source/images/* static/images/

and so on.

Theme

The first job was to create a theme. There are plenty of themes available, both paid and free, but after browsing them for sometime I decided I would try and reproduce my existing site as closely as possible and hopefully add some enhancements on the way.

For this I started with the Blank theme, git cloning it into the themes directory, then I simply deleted the .git directory and developed the theme in-location (rather than messing about with overriding it).

The blank theme comes with no CSS framework, usually I use vanilla Bootstrap but today I was feeling adventurous and I decided to try Tailwind.

Tailwind turns the traditional CSS approach on it’s head by making you add classes to your HTML elements to style them, and in theory you would not even edit a CSS file.

For Hugo however this didn’t work (I can’t edit the HTML rendered from markdown) but I was able to add @apply directives to elements in the “input” CSS file which would “import” the Tailwind styles:

a {
    @apply underline;
    @apply text-blue-900;
}

I spent lots of time tweaking the theme, so it’s possible slightly better looking than the original blog.

URLs

The default URL scheme was different from the Sculpin default. I was able to fairly easily change the scheme to more-or-less match:

{
    "permalinks": {
        "posts": "/blog/:year/:month/:day/:slug/",
        "categories": "/blog/categories/:slug/"
    }
}

Some URLs will be different however as Sculpin used the file name, where as Hugo uses the post title.

Sculpin gets the blog post’s date from the filename, whereas Hugo gets it from the “front matter” so I wrote a quick VIM macro to add date: 2022-01-01 to the front matter (using the filename to get the date).

Maps and other customizations

I added a support for rendering routes on maps and showing bike time and daily distance to my original blog.

Porting this was relatively simple, I copied the original Twig template then basically was able to map the variables and functions fairly easily to Hugo.

Audio

Sculpin would render HTML if it was embedded in the markdown, enabling me to embed an audio player. Hugo does not allow this by default but I was able to use a feature the shortcode feature to basically create a HTML macro.

Building

I created a simple Makefile to run both the tailwind command and the hugo command to build the site.

Summary

Hugo:

  • Renders the site extremely quickly.
  • The --watch flag actually works.
  • It hot-reloads the page in the browser on changes.
  • Very customizable.
  • Built-in “server side” syntax highlighting.

Tailwind:

  • Bit weird to start with but gets more comfortable.
  • Can still use CSS the CSS way via. the @apply directive.

I also managed to make some improvements:

  • Posts now show the correct date.
  • The home page has a tag cloud.