Switching to Hugo from Nikola
I have been using Nikola to build this Blog. Its a great static site build system that is based on Python. However, It has some crazy amount of dependencies (to have reasonable looking site). It uses restructured text (rst) as the primary language for content creation.
Personally, I use markdown for almost every thing else - taking notes, making diary, code documentation etc. Furthermore, given Nikola tries to support almost everything in a static site builder, lately its is becoming more and more bloated.
Case in point, recently it got support for shortcodes and although that did enable me to write posts in Markdown, but it is so difficult to develop them (It does not help to have almost no documentation/guide for their development). They are heavily tied to the plugin system with light support for template based shortcodes.
I really have nothing against Nikola. However, I did not feel at home - I wanted a light system that focused on markdown and had all the flexibilities that I wanted. My research soon brought me to Hugo.
Hugo is a light weight, fast and modern static website engine written in go. It literally
takes just milliseconds to build your entire site. For the given lightness, it is highly flexible
as well. You can organize your content however you want with any URL structure, group your content
using your own indexes and categories and define your own metadata in any format:
JSON. I was impressed! Keep in my mind,
python is still my primary language of programming
for scripting and machine learning. And, I have almost no programming experience with
YAML for all the configuration as well as metadata. In my next step to make this move,
I had to choose the theme for my blog. If you have been following me, I have been using several
flavors of bootswatch themes. So my first goal was implement my heavily modified version of
bootswatch theme in Hugo.
Developing a theme from scratch (Well, the implementation from scratch, as I all I am trying to do is mimic/improvise my current theme from Nikola) turned out to be a great adventure and learning exercise. It helped me understand the Hugo architecture in great detail. It did help to have some good documentation written for developers, not users! Although, Hugo's documentation can surely help itself with some cleaning and some fresher looks!
Hugo uses go templates with many extra functions and set of variables provided by Hugo. I personally feel Hugo's template-ing system to be more flexible and easier than mako - the one used by default by Nikola.
I converted almost all of Mako theme from Nikola website to Hugo's format and architecture with
additions (copied features and code) from a nice theme called
TranqilPeak. In particular, I liked their
fonts, search feature for taxonomies pages. Copying these features also meant I had to learn a bit
css. You can find a working copy of my theme in the
src branch of
gihub repository of my blog. I plan
to release this theme as a standalone theme in near future though.
Given I am using a bootstrap based theme, I like having a lot of its features available to me when I am writing in Markdown. The powerful template based shortcodes in Hugo provide a great way to write custom HTML code inside markdown. I feel Hugo shortcodes are so powerful, you could develop your own grammar of markup language in it! :yum:
Some of my shortcodes are basically based on bootstrap classes like panel, label, emphasis,
highlighted text, and block quotes. I also liked the figure command provided by restructured text
in Nikola. Luckily, same features are available in Hugo using a default shortcode called
Hugo also provides several other useful default shortcodes like
referencing other posts etc.
I have also some additional shortcodes for code-blocks and math. I will be detailing about them in a bit more detail in the next section. All of my shortcodes are available with the theme in the same github repo.
While converting to Hugo was fun, there were some caveats. The issues I faced were mainly with home
page, site search, and
ipython notebook posts.
Getting home page to work was very simple. Hugo documentation page provides a very clear details
about order in which various templates are looked. For home page, you will need to provide a
index.html. Then Inside the
content folder, you can put the metadata and the
content for the home page in a file named
I also added following template code in the index.html template to get list of posts with machine learning related tags.
Hugo has support for several output formats, including HTML and JSON. For implementing tipue search, we need to generate a JSON file with site content. This can be done by adding following to the configuration file:
and, using the following
Now, include the following
css in the
<head> of your pages:
modal code is needed to display the search results, preferably at the end of the
body of the HTMLpage:
Finally, the following
And, of course you will need a form/input for performing the search:
Although, by default Hugo provides code highlighting using the pygments, I
prefer to use client-side highlighting using prism.js. I also use the
following plugins of
prism.js for line numbers, highlighting and
cleanup of white space:
Finally, I create a shortcode called code-block to add relevant classes and variables around
<pre> tags so that prism could highlight code correctly.
One of the advantages of using Nikola is that, it provides native support for writing Blog posts in
But, on some Google search, I found this neat solution.
In summary, the setup is very simple - Use the linked
jupyter.css file in your template, then add this
file to relevant pages. I do the this based on a metadata variable
notebook: true via the
following template code:
Then for any jupyter notebook, convert it to basic HTML using the following command:
Finally, create a markdown file for your post to put the contents of this HTML file. Works like charm since markdown supports including raw HTML code!
I used katex for using math in markdown. I was having some issue
with the multi-line display math equations, so I created a shortcode called tex to write HTML
code explicitly so that
katex could handle that easily.
I added following code in the
<head> of all of posts:
And the following script at the end of the
Now, whenever, I need to add math equations in a post, enable the
hasMath: true parameter in its
So there you have it. I have my Blog now up and running with Hugo. Hope I will be more active here, since it now takes only seconds to deploy once I have a post written. No excuses now! 😜