Frontier Software

Robert Laing's programing notes

Hugo Basics

By Robert Laing

Figuring out how to use Hugo I hit the common snag of Where to start?. One of the reasons I picked Hugo is it’s documentation seemed pretty good (which is surprisingly rare for documentation systems) and it includes a step-by-step Quick Start guide.

But getting more advanced I found tricky since Hugo’s documentation isn’t very linear after the introductory material. Here I found a series of youtube videos very handy.

Hugo follows a style of programming I’m prejudiced against: plagiarising something to get broadly what you want, and then tinkering with it to get more specifically what you want. Ruby on Rails termed this style of programming Convention over Configuration, turning web application development into more of a paint by numbers exercise than creatively starting with a blank slate. Artistic feelings aside, if what you want is fairly conventional, configuring something ready made is far more likely to lead to a finished product on time and budget.

The quick start guide’s third step, Add a Theme, is easier said than done when looking at the vast selection. I went with Techdoc since it has a table of content sidebar, which is a key requirement.

hugo new site myproject
cd myproject/themes
git clone
cd ~/myproject
cp themes/hugo-theme-techdoc/exampleSite/config.toml .
cp -r themes/hugo-theme-techdoc/exampleSite/content .
cp -r themes/hugo-theme-techdoc/exampleSite/static .
hugo -D

The last command creates a public subdirectory, containing and index.html file along with subdirectories for css, images, js and ones for each section of the documentation which we’ll get into shortly.

A tweak needed to get the site working with nginx or whatever web server is to edit the first line of the config.toml file baseURL = "" to whatever your domain is. Hugo supports three formats to set global constants in, and it’s my first encounter with toml. I was familiar with yaml and Json before.

The myproject/config.{toml,yaml,json} file is one of several that Hugo expects to find with specific names and locations. These contain configuration information to be overridden as you tweak the provided example to your own needs.


The skeleton provided by hugo new site myproject provides a layouts directory, but omits a layouts/_default subdirectory which is likely to be needed to house the baseof.html, list.html, and single.html which are parent templates.


This is the template of the overall html page.

Base layout

<!DOCTYPE html>
{{ with .Site.LanguageCode }}<html lang="{{ . }}">{{ else }}<html>{{ end }}
{{- partial "head.html" . -}}
{{- partial "custom-head.html" . -}}
{{- partial "prepend-body.html" . -}}
<div class="container">
{{- partial "notification.html" . -}}
{{- partial "site-header.html" . -}}
{{- partial "global-menu.html" . -}}
<div class="content-container">
{{- block "main" . -}}{{- end -}}
{{- partial "content-footer.html" . -}}
{{- partial "powered.html" . -}}

{{- partial "sidebar.html" . -}}
{{- partial "footer.html" . -}}

Go’s template package delimits actions between double open and closing curly braces. The most basic is {{ pipeline }}, defined in the documentation as:

A pipeline is a possibly chained sequence of “commands”. A command is a simple value (argument) or a function or method call, possibly with multiple arguments:

Leading minus signs as in {{- strips white space before the inserted content, and trailing minus signs as in -}} strips white space after.

Some template functions, such as partial are specific to Hugo, explained in partial templates. When asked to insert {{ partial "foo.html" . }} Hugo looks for “foo.html” first in layouts/partials/<PARTIALNAME>.html and then in themes/<THEME>/layouts/partials/<PARTIALNAME>.html — ie overridding the default involves coppying the original provided by the theme into layouts/partials of the project root directory and editing it.


Last updated on 6 Jan 2021
Published on 6 Jan 2021

Content Footer