Hugo: The Best Static CMS

If you’ve been reading this blog for some time you’d know that I like to try different CMSs. I made some mistakes over the years and I transferred my posts between different CMS. This ended up killing a lot of my backlinks, but that’s ok. I ended up settling on using Markdown to write my posts (love it) and a static CMS generator. Originally I used Pelican and it was pretty good. It was based on Python and had some really neat ways to slice and dice your posts, leverage SEO, and do cool things with it.

However it was SLOW in building the entire website. Sometimes it would take 10 minutes to build my website, whether it was for production or running the development server. I just resigned myself to dealing with these speed issues because I was getting into a groove with Pelican. It works, who cares if it was slow.

Then I discovered Hugo.

Enter Hugo

I’ve been taking an Udemy course in learning Go Language (GoLang) and like how simple it is. The course has been one of the best ones I’ve ever taken and I’ve learned many of the basics of computer programming. It reminded me of my Fortran course in college! The beauty of GoLang is that it takes advantage of multiple CPUs with ease. It’s very easy to program in the language and it makes the complex very simple. In some ways it reminds me of Python BUT it’s statically typed and compiled. That’s a BIG plus in my eyes because I’m getting annoyed at all the dependency issues with Python. If it compiles, it works!

Hugo generates my site in like 20 seconds compared to the 10 minutes it took Pelican to do the same thing. Yowzers, that’s FAST!

Of course there are a few little best practices we need to follow AND here’s what I learned using Hugo so far.

Yaml Front Matter Is Best Imho

YAML, a front matter format, is the way you tell the static generator what the blog post is about. You can tell the generator what category the blog post is in, what the permalink is, title, date, and so on. It starts with three —’ and ends with —’. I was introduced to YAML when I used Jekyll, the ruby based static generator. Ruby has it’s own annoying problems and I dislike it too. When I migrated to Blot.IM, YAML was not used. I had to use one of Dave’s YAML to Blot converters and which essentially removed the —’s. Admittedly, this was a cleaner way of writing a post. I could do something like:

title:  my awesome title
date:  2020-05-15

Start writing my blog post here...

When I migrated to Pelican, it could just use the old Blot.IM format and all my posts would generate. Easy peasy, right? It wasn’t until I started getting annoyed by the generation speeds and devserver in Pelican that I considered making a move elsewhere.

Hugo has some specific ways you write posts and interestingly enough, they give you 3 options: TOML, YAML, or JSON. I found the JSON one interesting because GoLang makes working with JSON so easy and awesome. If you ever had to work with JSON data using Pandas you’d think you died and gone to heaven using JSON in GoLang.

I thought about what moving to TOML or YAML files would mean. In Blot.IM I could create new metadata information that would parse when I had at the top of my blog post, for example:

title:  my awesome title
date:  2020-05-15
new_metadata: something

Start writing my blog post here...

I thought that was pretty neat so I made things like: headerImage: \url\to\pic

or

twitter: name

which then allowed me to hack my templates.

I had to do this when I wanted to enable OpenGraph and Twitter Cards in Blot, which didn’t come native with the templates available. So yeah, Dev people like me kinda liked Blot.IM for giving us the ability to customize things. Still, this hacking was painful and eventually I got it to work well. I just wished there was an easier way.

Using YAML I was still able to do all those things and all I needed to do was add back --- at the top and bottom of the post. While the non-YAML way made things cleaner, the YAML way made reading data a bit easier for my eyes. I knew exactly what section in the blog post was dedicated to the Front Matter.’ With HUGO I could still define my metadata BUT I found out it had a plethora of predefined metadata (known as Front Matter Variables) that just works out of the box. This was pure heaven for me.

I started going down the rabbit hole then and discovered that I didn’t need to do all that Open Graph and Twitter Card hacking in Hugo that I had to do in Blot.IM. This is what sold me on Hugo going forward.

Internal Templates and Shortcodes

Lo and behold, Hugo made things easy by automatically internalizing Open Graph, Twitter, YouTube, and other things through the use of internal templates and shortcodes. Putting in Disqus and Google Analytics was easy as adding a line in your config.toml file (global config file for your blog) by doing this:

#DisqusShortname = "my-Disqus-name"
googleAnalytics = "UA-XXXXXXX-X"

Using a YouTube shortcode, you can easily embed a video by using it’s shortened URL reference like this:

All you need to do is call these variables in the your various page templates like this:

    
    
    

and the would just work. Easy peasy, lemon squeezy.

There’s also a section on Hugo Pipes which are meant for preprocessing things like images that I haven’t explored yet.

Just the YAML, internal templates, and shortcodes have made my entire blogging life so much easier. The only issue is writing a script or something to make sure I have all the required YAML in my blog posts. I think the answer might be in me building one of those Hugo Pipes.

Enable Unsafe Html In Markdown

Of course, there are some weird things I had to deal with in the basic set up of Hugo. For example, it restricts all HTML code in your markdown files by default. A lot of my old blog posts have HTML in it (from the Jekyll days) so I would end up with a lot of blank posts. I don’t remember where I figured this out but I had to add some parameters to the config.toml file so that it would accept unsafe HTML.’

It was as simple as adding the following to the config.toml file:

[markup]
  defaultMarkdownHandler = "goldmark"
  [markup.goldmark]
    [markup.goldmark.renderer]
      unsafe = true  # Enable user to embed HTML snippets in Markdown content.
  [markup.highlight]
    codeFences = false  # Disable Hugo's code highlighter as it conflicts with Academic's highligher.
  [markup.tableOfContents]
    startLevel = 2
    endLevel = 3

Enabling search in this particular theme I’m using is a bit of a pain but there are ways around them. Hugo does support using javascript types of search. Of course you can use Google to do it (and I just might go that route) but I’m working on getting that implemented here. It’s one of the missing pieces because a custom 404 page can only go so far.

End Notes

Hugo is powerful, fast, and makes blogging simple again. While there are some bumps in transitioning to this static generator, I think it’s the one that will be able to grow with this site. I look forward to writing more tutorials about over the next few weeks.



Date
May 21, 2020