On Building a Blog - Starting with Hugo

I didn’t want to be creating my entire blog from scratch - I want to use it to write about all the other things I create from scratch - so I decided to use Hugo. Hugo is a static site generator, which takes care of things like layout and navigation, and lets me pick from a heap of different themes to get a look & feel that I like. This (theoretically) lets me focus on just writing content. I did have to make a few configuration changes though to get my blog just-so.

How it works in practice

You could read through the Hugo guide, but it might be quicker for me to give a brief overview of exactly how I use Hugo, and it will help make sense of everything to follow.

I have a folder on my computer that represents my website. This folder is set up as a git repository, which means I can keep a complete change history of my site, and revert to an earlier version if I do something stupid. I write all my posts in Markdown syntax which just means I can get nice headings and things like bold and italics while using any old text editor.

When I want to create a new post, I just create a new markdown file in the /content/posts/ subdirectory, and when it’s marked as published the build process will include it on the public site.

Pick a theme

The “Quick Start” guide from the Hugo site was clear enough, and one of the steps in that process is to pick a theme. I chose hyde-hyde for my theme. The instructions gave me a couple of options for installation, and I chose to install it as a git submodule, for ease of updates.

The theme you choose has a pretty major impact on how easy it’s going to be for you to add different things to your site, so it’s important to find a good fit at the outset. Thankfully my theme was a good fit for what I needed, but this was better luck than management.

The “Quick Start” guide finished with the instruction to configure your theme, and explains that you can use a your config.toml file to do that. The problem is, that file is almost empty for a new site, and it wasn’t immediately clear to me where I could find the list of possible options. There were some options in the documentation for the theme, but there were others hinted at that weren’t listed. As it happens, the theme also comes with an example site (stored under the exampleSite folder within the theme’s subdirectory), and this site also contained an example config.toml file, with most of the available options listed.

Some of the changes I made:

  • enableEmoji = true because emojis are 👌
  • highlightjs = true under [params] because I found HighlightJS easier to use
  • under [params.social] I was surprised to discover I could add a GitLab account and it worked out of the box, despite not being in the original list

What about me?

I wanted to include a page that gives a summary of me, and the theme included an “About” page as a default option. I enabled the menu item for it, and created the about.md file under content…but when I looked at the page there were a few oddities. The page still showed a publish date and a reading time, just like on a normal blog post. I like these on the posts, but it seemed odd for an About page.

Looking through the configuration options, it didn’t look like there was a clear way to disable them. Thankfully - if you don’t like something about the theme you’re using, Hugo provides a really simple way to override parts of the theme. Things like layout and standard inclusions are stored in the layouts of the theme, which is (at least in the case of my theme) made up of a heap of partials. They can be thought of as components that when put together with other components make up a whole piece.

The partial I needed turned out to be post-meta.html with the part I needed to modify looking like this:

    {{ end }}
    <i class="fas fa-clock"></i> {{ .ReadingTime }} min read
{{ end }}

So I copied that file out of the theme and into my own /layouts/partials/page-single/ directory (matching the path from the theme), and added a condition around the ReadingTime section.

    {{ if not .Params.suppresstime }}
      <i class="fas fa-clock"></i> {{ .ReadingTime }} min read
    {{ end }}
{{ end }}

The suppresstime parameter is an example of a user-defined field. Now I can simply add it the Front Matter of my About page, and it will suppress the rendering of the reading time.

That just leaves the date to deal with.

Date vs PublishDate

There are several date fields in Hugo by default, but I’ll only talk about two of them. When you create a post using Hugo, like hugo new posts/some-new-post.md the front matter will already be populated with the date field, using the system time when you ran the command. This is fine, but I don’t want to display this date on the published page, as it often won’t be published for some time after I started.

Hugo also has a publishdate field, which I could populate manually, but I found that it wasn’t being used by default in my theme. To fix this I just had to find the layout partials that were using the Date parameter, and change them to use the PublishDate parameter. One of the partials I’d already copied out for the reading time fix, so I just had to grab the posts-list partial, and update it to show the date I wanted on the front page.

Customising the Favicon

The favicon is the little icon you see in the browser tab when you visit a website, and I didn’t want to keep the default Hugo favicon. Thankfully there is a fantastic website called favicon.io that lets you (among other things) pick an emoji to use as a favicon. It even exports it in a ton of different formats so it will work across lots of different devices!

Once I had my set of favicons, I just needed to copy them into the /static/ folder so they’d be available after the site was built, and configure my site to use it. This required copying out the header.html partial so I could override it, and pasting the links favicon.io gave me inside the <head> block. Note that my theme already had a couple of links in there for the original favicon, so be sure to check for more than one link if you’re doing this.

Thanks for reading. Toodles!