After updating my SDF site to Hugo’s spiffy Terminal theme yesterday I had mentioned on Mastodon that I hadn’t actually put any new content on the site in quite a while. I got a good recommendation from another SDF user to maybe put something together about how I made the site. The goal here won’t be to replace Hugo’s own documentation, but to supplement it and provide an SDF-specific spin where necessary.

Hugo, What Is It?

I’ve already thrown out the word “Hugo” a couple of times so let’s start with what the heck it is. Hugo is a static site generator. If you have no idea what that means, static site generators essentially allow you to author content in some type of markup language and then compile that content into HTML. Why on Earth would you want to do that? There are a few reasons. First, it’s much easier and cleaner to write content in something like Markdown than in HTML. The real benefit, though, is that you can very quickly and easily change your entire site without having to touch every file. This is because static site generators use partial HTML templates referred to as… “partials”. These partials will define what just a portion of the site looks like. For example, there’s a partial for what the header will contain on every page, what the footer will contain on every page, what the post content looks like on every page, etc. If I need to change the footer on every page, I just have to update the partial, recompile the site, and now the change has been applied everywhere. I don’t need to use sed to touch every HTML file on my site.

Hugo is a far cry from being in the only static site generator out there; Jekyll was one of the first to become popular given how it gets promoted with GitHub Pages, and there are plenty of other ones floating around, too. I personally like Hugo over Jekyll, though, because:

  1. It’s a single compiled binary. You don’t need to worry about setting up a Ruby environment.
  2. Being compiled rather than interpretted means that it can compile large sites much more quickly than Jekyll.
  3. Since everything is a text file it’s easy to back up and move if needed. Details on that later.

The astute out there may be asking, “Why use this instead of WordPress, Ghost, or any other blogging platform?” Again, there are a few reasons. Foremost is that most blogging platforms involve a content management system (CMS.) A CMS is going to be much more involved requiring a database to be secured and maintained along with needing more computing power to run your site. If your goal is to just host content then a static site generator is much simpler. That being said it’s important to recognize that the static part is important; if you’re wanting a lot of interactive content on your site then this is likely not the best way to go. While you can do things like get Disqus comments embedded, remember that just because you can doesn’t mean you should.

Getting Hugo

Getting Hugo is simple. Just head to their GitHub Releases and download the latest. At the time of this post the following command will download the latest version for the SDF MetaArray.

wget https://github.com/gohugoio/hugo/releases/download/v0.59.0/hugo_0.59.0_Linux-64bit.tar.gz
tar -zxvf hugo_0.59.0_Linux-64bit.tar.gz
mv hugo ~/bin/
rm hugo_0.59.0_Linux-64bit.tar.gz LICENSE README.md

This extracts the tarball, moves the hugo executable to my local bin directory, and removes the unwanted files. Note that I’ve got ~/bin in my $PATH so that I can easily call hugo. The following is in my .profile for Bash:

PATH=$PATH:~/bin

Making A Site.

Now that Hugo is on the system it’s time to fire it up and create a site. Hugo will generate everything you need to get started if you run:

hugo new site blog

You can call the site whatever you like in this command; I just opted for “blog”. Note that the directory containing the site will be named that. If you list the contents of that directory you’ll see several important files. The Hugo documentation gives a good breakdown of them, but I’ll just call out a few.

config.toml is the file controlling the overall setup of your site. Things like the title, menu options, header metadata, pagination, and more are controlled here. We won’t look at it until we pick a theme, though, since the theme will often dictate what options we can use in this file.

The content directory is where Markdown files will live. Since my Hugo sites have all just been blogs, the only thing in it is a directory called posts which holds, you guessed it, the files for my posts.

public is where the compiled site will live. When Hugo parses Markdown and partials into HTML, the result gets dumped into public. Later we’ll move this to where SDF needs our HTML so it can be hosted.

static is, unsurprisingly, where static assets go. For example, I create an “images” directory there to hold any imagery I may use for my posts. Anything placed in static will end up in / of your site.

themes is where you’ll put themes at. It’s 100% possible to make your own, but I have no interest or desire to do that, so you’ll want to look somewhere else for information on getting started with that.

Theme It Up

Hugo has a nice theme gallery you can browse to find one you like. The current one for this site at the time is Terminal. If you find one you like, right-click on the Download button and copy the link. This will give you a .git file for the theme’s repository over on GitHub. You can copy it to SDF via:

cd ~/blog/themes
git clone https://themes.gohugo.io/hugo-theme-terminal/

Obviously change the URL to your desired theme. In changing directory, replace “blog” with whatever you named your site. Now that we’ve got a theme it’s time to update that config.toml file. Most themes will offer a sample configuration file; for example, check out the “How to configure” section of Terminal’s page. I’d recommend wholesale copying that sample config and replacing your own with it. Going through all of the options will be exhausting so leave them as-is for now and start playing around with them later. One thing I will recommend you change, however, is baseurl. As I mentioned in a previous post, this is a good place to ensure all links on your site are leveraging HTTPS rather than constantly forcing a redirect. So mine looks like:

baseurl = "https://failtime.sdf.org/"

Yes, the trailing / is important; be sure you’ve included it to avoid weirdness later.

Make A Post

Hugo is able to automatically give you a skeleton Markdown file for a new post with the appropriate front matter. “Front matter” is just a fancy way of saying headings in the file that define things like the title of the post, the author, any keywords you want to associate with it, etc.

cd ~/blog
hugo --cacheDir ~/temp/ new posts/first_post.md

Note that we’re doing something SDF-specific here. The current version of Hugo wants to create file caches that by default live in /tmp/hugo_cache which you won’t have access to on SDF. I have created a temp directory under my own profile and I’m using --cacheDir to override that default. If you fail to do this, you’ll see something like:

Error: add site dependencies: create deps: failed to create file caches from configuration: mkdir /tmp/hugo_cache/blog: permission denied

Authoring Content

With the file created just open it in your editor of choice. From our last example the file will live at ~/blog/content/posts/first_post.md. If that editor isn’t vim, you’re wrong but I forgive you. You’ll see the front-matter at the top; just fill in what you want as it’s all optional. I would recommend at least giving your post a title, but don’t let me tell you how to live your life (you know, unless it’s about your text editor.) Just remember that the content your post should all be in Markdown. If you need to know how to do something in Markdown I’ve found this cheat sheet to be pretty solid.

Publishing Content

With your post written and saved now we’ve got to take a few steps to get that content on the Internet at large. Note that I’m assuming you’ve already set up your SDF web page and that you’ve moved it to the MetaArray if that’s where you want to be hosting it. If you haven’t done either of those just follow the tutorials. The steps we need to take now are:

  1. Compile the site.
  2. Move the resulting build to our html directory.
  3. Re-permission the files.

These steps can be done independently, but I put them into a simple shell script for my own sanity. Note that just running the hugo command with nothing else while in the root of a directory created by Hugo will compile the site; we’ve just got to specify the --cacheDir switch again. After that I use rsync to copy the build from the public directory to ~/html, which is where SDF is hosting my content. Since these are new files I use mkhomepg -p to make sure the permissions are all set.

#!/bin/bash
cd ~/blog
~/bin/hugo --cacheDir /meta/f/failtime/temp/
rsync --delete -r ~/blog/public/ ~/html/
mkhomepg -p

That’s it! You should be able to visit your SDF site and see the new content now live!

Backing Up Your Site

I mentioned at the beginning of the post that one of the advantages of a static site generator was that it was simple to back up and move if needed. If something were to happen to SDF or if I really needed to move my site for whatever reason, it would be simple to basically copy all of my ~/blog/ directory to another machine. I periodically back up my site by just making a tarball via:

tar -zcvf hugo_bkp.tar.gz blog

Then I just copy the tarball to wherever I want to keep it safe at. Then recovering from even a complete rebuild of the MetaArray would be a simple matter of re-downloading Hugo and expanding out my tarball. Simple!