Hugo

Creating/coding for the web is not my primarily focus but i think it is an important skill to have and will be increasingly so. As part of a 1 year program in business and marketing I did almost 20 years ago we had a short course in web development. The instructor insisted that we should use Dreamweaver (Macromedia at the time now Adobe). I did not like it, I thought it hid the internal mechanics and I wanted to get closer to the actual language so I ended up writing everything in notepad. Looking back at it now it makes sense. By manually writing the html you get a better understanding how it all fits togehter and it all gets demystified somehow. For me that is definetly my style of learning, take away all the supporting frameworks and start with what makes it tick. When you understand how it fits together, you could start looking att things that makes it faster/easier to use.

My next step was to use Flash (also a Macromedia product at the time). This was my first encounter with programming and I loved it. I did html and flash for a couple of years. I really enjoyed using Flash (particularly with AS3) and I used it on many projects to creating “functional” UI mockups. Then along came html5 and I started looking at other alternatives to create websites. I used Wordpress for a couple of years, then I did my own custom php cms soloution.

Then I started looking at static site generators. The first couple of years I used Jekyll. It worked ok, but since it is written in Ruby, which I dont use at all, I couldn´t really fully embrace it, but it worked ok. Then, a few years later, after changing my main workstation, I thought I have a look for a new static site generator. Since I am really comfortable with Python I naturally tried Lektor, but since the forum around Lektor does not seem so active, I looked further and decided to try out Hugo, a static site generator written in Go. And I really like it, here are a few things I like:

  • Good documentation, forum and tutorials
  • A really nice CLI
  • Easy to setup custom pagination
  • Logical, robust and really fast
  • Syntax highlighting is included and easy to setup
  • The server with auto-load/refresh
  • Automatic TOC creation

So this is the latest stop of my web journey. Below are some notes I took when getting to know Hugo!

List pages

Hugo will automatically create a list page for all 1st level subdirectories of the content folder. If you want Hugo to create list pages for deeper subdirectories we need to create a file called _index.md in that dir. we can also add content in this md file that will be displayed in the list page. If we want to add content to a first level subdirectory list page we can also create a _index.md file (note that the list ok age will be created regardless of this file)

Archetypes

Is the template used to control which front matter is created and populated when we run: hugo new page.md In the archetypes dir we find the default.md which is the default template used for new content. We can also create a specific template for content created in a specific content folder. The we call the archetype md file the same as the content dir.

Taxonomies

We can add the keyword tags and categories to our front matter and Hugo will create a list page structured based on the values. Tags and categories are the default taxonomies. If we want to use custom ones we need to specify this in the config.toml file

Templates

List and page templates templates for list and single pages are stored in a directory called _default in the layouts directory and are called list.html and single.html. The list and single page layouts stored in the _default directory are, as the name suggests, the template used by default for all single and list pages.

Section templates

But we can create special templates used for different content sections. These templates are called section templates. To do this we create a directory with the same name as the directory for the content we wish to create the template for. Lets say we have a directory called dir_c in the content directory. To create section templates for the content in this directory we create a directory in the layouts folder called dir_c. In the directory we can create list.html and single.html

Home page template

The home page is technically a list page so by default it uses a list template but we could give the home page its own template. We do this by creating a template in the root of the layouts folder called index.html

Base template

The base template are, as the name suggests, the template that are the base of all other templates. To create this template we create a file called baseof.html inside the _default directory inside the layouts directory.

<!DOCTYPE html>
<html>
<head>
	<title>{{ .Title }}</title>
</head>
<body>
	{{ block "main" . }}
	{{ end }}
</body>
</html>

And to use this baseof template we write the following (in the layout that we wish to implement the base template)

{{ define "main" }}

	The content will be rendered here...

{{ end }}

Note that we can use more blocks in the base template if we want. We can for instance create a footer and in the base template block add some default content that will be displayed if the block is not defined in the child template. If content is defined in the block (i.e. content is inserted inside the block when it is defined in the child template, it will be used and overwrite the default content)

Variables

Hugo’s templates are context aware and make a large number of values available to you as you’re creating views for your website. We can for instance use variables defined in the front matter, these are called page variables. To acces the title, date and url we use the syntax below.

{{ .Title }}
{{ .Date }}
{{ .URL }}

If we create some custom front matter variable we need to access it using the Params keyword.Lets say that we hava a key-value pair in the front matter specifying the_answer: 42. If we want to access it in the template we can use the following syntax:

{{ .Params.the_answer }}

Functions

To loop through the pages we can use the range function and provide the .Pages as the collection we wish to iteraste through.

{{ range .Pages }}
	{{ .Title  }}
{{ end }}

Partial

SVG

Using dict to pass multiple values to a partial The partial below creates a SVG and expects fill, height and width from the caller: hugo docs

Logic

Here is an example of how to use the if .. else if .. else We declare some variables (in a template) and display the result.

	{{ $a := 5 }}
	{{ $b := 1 }}

	{{ if eq $a $b }}
		(A) {{ $a }} is equal to (B) {{ $b }}
	{{ else if lt $a $b }}
		(A) {{ $a }} is less then (B) {{ $b }}
	{{ else }}
		(A) {{ $a }} is greater then (B) {{ $b }}
	{{ end }}

Note that the comparasion operators is not the “typical” ones like == instead we use:
eq ==
lt <
le <=
gt >
ge >=
and &&
or ||
not !=

If we use the and && statement it looks like this:

{{ $a := false }}
{{ $b := false }}

{{ if and ($a) ($b) }}
	{{ $a }} and {{ $b }} both are true
{{ else }}
	{{ $a }} and {{ $b }} one or none is true
{{ end }}

The or || operator looks like this:

{{ $a := false }}
{{ $b := false }}

{{ if or ($a) ($b) }}
	{{ $a }} and {{ $b }} one or both is true
{{ else }}
	{{ $a }} and {{ $b }} neither is true
{{ end }}

Data files

Lets loop through a json data file. We have the following json file in our data directory:

{
	"Batman":{
		"name":"Bruce Wayne",
		"universe":"DC"
	},
	"Ironman":{
		"name":"Tony Stark",
		"universe":"Marvel"
	},
	"Black Widow":{
		"name":"Natasha Romanova",
		"universe":"Marvel"
	}
}

To iterate through the data and print the name and universe inside an unordered list we can use this syntax:

<ul>
{{ range .Site.Data.superheros }}
	<li>{{ .name }} - {{ .universe }}</li>
{{ end }}
</ul>

If we want to also include the key (the superhero name in this case) we use this syntax:

<ul>
{{ range $key, $value := .Site.Data.superheros }}
	<li>{{ $key }} : {{ $value.name }} - {{ $value.universe }}</li>
{{ end }}
</ul>

Syntax highlighting

To generate a stylesheet using the monokai style you can run this:

hugo gen chromastyles --style=monokai > syntax.css

Run hugo gen chromastyles -h for more options. Here you will find a gallery of available styles.

I like using GitHub flavored code fences to add syntax highlighting. To enable this, set the pygmentsCodeFences to true in Hugo’s configuration file.

I also modified the highlight class in my main stylesheet to get the look I wanted:

.highlight{
	width: 100%;
	border-radius: 3px;
	background-color: #272822;
	margin-bottom: 15px;
	padding-left: 3px;
	padding-right: 3px;
}

Markdown & Images

To view an image generated from a markdown file I needed to add the following to the config.toml

canonifyURLs: true

Then I could use:

![](/images/pic.jpg)

Some links: