Moving from jekyll to Hugo

As you might have noticed this blog was previously generated using Jekyll but was migrated to hugo for performance reasons, for more about the performance differences read my previous post on the subject.

Thankfully the migration process is rather straightforward, but I thought it might be a good idea to write a little about it.

Since Hugo and jekyll both uses markdown the differences will be rather small but I will describe the process for both post as well as for the config files.

Getting started

To get started you will need to download and install hugo, this can be done by the following commands:

hugo_0.13_linux_amd64.tar.gz
tar -xvf hugo_0.13_linux_amd64.tar.gz
sudo mv hugo_0.13_linux_amd64/hugo_0.13_linux_amd64 /usr/local/bin/hugo
rm -rf *.tar.gz hugo_0.13_linux_amd64
hugo new site MyAwsomeSite
cd MyAwsomeSite

You will also need a theme for your new blog, and since I am biased I will show you how to install the same theme as this blog, this does however require git.

git clone https://github.com/SenjinDarashiva/hugo-uno.git themes/hugo-uno
To build your site you can now use the following command:

hugo server -D -t hugo-uno
This will build all drafts and start a local server which shows you the current state of your site.

Post

Now that you have a new hugo site ready you might want to move the posts from your old jekyll site into hugo. To achieve this we will need to alter the front-matter slightly, the following is a basic front-matter for a jekyll post:

---
layout: post
title: Moving to Jekyll
summary:
status: draft
---

While a basic front-matter for a hugo post looks like this:

---
title: "Moving to hugo"
description: ""
date: "2012-04-06"
draft: true
---

As you can see we are missing some information, mainly the date which for jekyll posts is specified in the file name. The layout definition for a jekyll post is handled by the use of folders in hugo.

So to achieve the a new post in hugo we will use the following command:

hugo new post Moving-to-hugo content/post
With this step done we simply copy the content of our jekyll post into the new hugo post and set an appropriate date.

This manual approach works fairly well for a small number of posts, however if you have a large site this needs to be automated. For this purpose I have created a small script that does the following steps:

  • Parse each post in temporary folder
  • Create appropriate folder for layouts
  • Copy file to appropriate folder
  • Replace summary with description
  • Remove Layout
  • If status == draft remove status line replace with “draft: true”
  • Add date, parsing date from filename

With these steps done you still need to make sure that all your static resources (js,css,img) is correctly linked on your new site.

The script is available at github

Config

As for the config files, if you are using a standard jekyll config file withouth any major changes from the basic one generated by:

jekyll new site

You basically copy that config to your hugo blog, rename it to config.yml and add a specified baseurl, with these steps done you should have a working hugo blog.

Issues

With the basics covered I will dive into some of the issues you might face, especially if you have a complex setup using plug-ins or if you have large amounts of code highlighting.

Since both hugo and jekyll provide code highlighting this is not a major issue, however hugo uses a different notation than jekyll meaning that you have to replace

{% highlight ruby %}
def print_hi(name)
  puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.
{% endhighlight %}
With:
{{ < highlight ruby >}}
def print_hi(name)
  puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.
{{ < /highlight >}}

I have added a space between {{ and < to allow the code to be rendered on this page.

As for plugins you will have to review the plugins you currently use and see if there is any hugo replacements, sadly hugo does not come with the same amount of plugins as jekyll. However most standard functionality should be available.