I have moved my blog from an old version of Jekyll over to Hugo. The reason for the change is mostly that my Jekyll setup was very old, and the way I had implemented a couple of custom plugins meant I needed to run the server before generating the site. Also I am not using ruby as much as I use to, and Hugo is “new”, shiny and written in go.

Theming

In porting the site to Hugo I also got rid of bootstrap, it has served me well, but with modern browsers having support for things like CSS Flexbox the benefit for simple sites is negelible. I really like Flexbox, though it can still be a bit confusing from time to time, especially grow and shrink. But it is awesome that you can do stuff like justifying content, do wrap-reverse or specify a order, all of which helps when trying to make a site responsive.

I have used order to make the page header go to the bottom when browsing on small screen. This means that the content of the page comes up front, and you don’t have to scroll a full page to get to what matters.

Templating

Since Hugo’s templating language is the Go html/template, which is quite similar to Liquid used in Jekyll, it is not too har to figure out how to structure the templates.

If you have ever done any work with the Django Framework for Python, you will be familiar with how Hugo does templating. It allows you to define blocks and overwrite them in subtemplates.

# in base template
{{ block "some-name" }}Default content{{ end }}`

# in sub-template
{{ define "some-name"}}My overwrite content{{ end}}

In general the Hugo documentation is quite good, only a couple of times I stubbed my toe on the way Hugo does things.

  • To get Jekyll like YEAR/MONTH/DAY/title paths you can set the permalinks for specific content types.
  • I also wanted my atom feed to keep being named atom.xml.
  • If you want tags and categories to be usable, you need to define taxonomies.
[permalinks]
posts = "/:year/:month/:day/:slug"

[outputFormats]
[outputFormats.RSS]
baseName = "atom"

[taxonomies]
tag = "tags"
category = "categories"

Redirects

You may note that I changed to using /:year/:month/:slug since I could not see a reason for keeping the day folder. This means I have setup redirects that strips out the day part of the url, to preserve incoming links.

The Nginx rule I use for doing the redirects is just a simple location match.

# Match /YYYY/MM/DD/whatever and returns /YYYY/MM/whatever
location ~ "^(/\d{4}/\d{2})/\d{2}/(.*)$" {
  return 301 $1/$2;
}

Deployment

My old way of deploying used Capistrano which is a nice ruby tool. However the number of times I have run into not having Capistrano installed is countless. And it does not help that my old deploy scripts are written for the now defunct Capistrano 2. The suggested way to deploy Hugo is to run hugo && rsync -avz --delete public/ your_server:path, which is nice and simple. It does not require me to install anything in order to deploy, which I really like. Though it should be said that I could do the same with my old Jekyll blog.

For all of 2016 I only wrote one blog post, and none in 2017. I am not sure how many I will get around to write in 2018 and beyond, but at least now I feel it should be easier than ever.