Hugo templating basics

Go templates is the flexible templating language used in Hugo. In this lesson we'll go over basic Go templating concepts and see how you can use it on your site.

Lessons in this Tutorial

Hugo Beginner Tutorial Series

With Hugo templating, you can control how your page is rendered. You can use variables, loop over arrays, check conditions, and run functions. Think of it as a simple programming language to help build the pages on your site. Those curly braces in your layout {{ }}, that’s Hugo templating.

What is front matter?

Front matter is a snippet of metadata at the top of your content files. Some of the metadata will be specifically for Hugo, for example, setting a layout, or indicating the current page is a draft. Other forms of metadata will be specific for your site, for example, indicating which type of hero to use on the page, or a list of your top five favorite foods.

Front matter comes in the form of a small YAML snippet at the top of content files. We’ve seen this on both the index and about pages:

/content/_index.md
---
title: Home
---

It might not look like much, but we can reference this front matter in our layout using Hugo templating.

What is Hugo templating?

Hugo uses Go templating as its templating language in layouts. It’s easy once you get your head around it. As with many things in Hugo land, sometimes it’s easier to show rather than tell.

Examples of Hugo templating

Output a string

Example
<p>A Go template is a normal HTML page. When you want to execute a piece of 
code, you can use double curly braces like this: {{ "Hello!" }}.</p>

Output from front matter

Example
<!-- You can reference a variable from your front matter in a layout with .Params. For example, you 
could output the title on your pages with: -->

<title>{{ .Params.title }}</title>

Output from site configuration

Example
<!-- Sometimes you'll want to set a variable globally in your config.toml. 
Hugo has already initalized a title in your config.toml. You can access
a variable from your global config with site. For example: -->

<title>{{ .Params.title }} | {{ .Site.title }}</title>

Conditions

Example
<!-- We might want to check if the front matter title exists. If
it exists, output it; if not, use the global config title. -->

{{ if isset .Params "title" }}
  <title>{{ .Params.title }}</title>
{{ else }}
  <title>{{ .Site.title }}</title>
{{ end }}

Set and output a variable

Example
<!-- variables at set with a $ sign. For example: -->
{{ $favorite_food := "Gazelle" }}
{{ $favorite_food }}

Looping

Example
<!-- In Go, an array that can change size is called a slice.
You can iterate over an array or slice using range. -->
{{ $best_friends := slice "pumbaa" "timon" "nala" "rafiki" }}

<ul>
{{ range $best_friends }}
  <li>{{ . }}</li>
{{ end }}
</ul>

Nested Key values

Content file:

Example
---
title: Appearance
apperance:
  eyes: green
  snoot: boopable
  whiskers: true
  limbs:
    - claws: 5
      side: left
      position: front
    - claws: 4
      side: right
      position: front
    - claws: 3
      side: left
      position: back
    - claws: 5
      side: right
      position: back
---

Layout file:

Example
<!-- If we want to output all of these variables, we could call 
.Params.appearance.x for each one. Instead we could use `with` to change 
the context to '.'. It also has the benefit of checking whether the 
variable exists and won't run the block if it doesn't. -->

{{ with .Params.appearance }}
<h3>My top appearance traits</h3>
<dl>
	<dt>Eyes</dt>
  <dd>{{ .eyes }}</dd>

  <dt>Snoot</dt>
  <dd>{{ .snoot }}</dd>

  <dt>Whiskers</dt>
  <dd>{{ .whiskers }}</dd>
	
	{{ with .limbs }}
    <dt>Claws</dt>
    <dd>
	    <ul>
      {{ range . }}
        <li>{{ .position }} {{ .side }} {{ .claws }</li>
      {{ end }}
      </ul>
    </dd>
  {{ end }}
</dl>
{{ end }}

These are the foundations of templating. You’ll be using all of these concepts throughout your Hugo journey. You can browse through the templating documentation to get an idea of what else you can do.

If you like to keep your HTML output tidy, you can use {{-</code> and <code>-}} to trim the whitespace surrounding the tag. The Hugo documentation has a great example of this.

Putting it all together

Let’s put our new Hugo templating knowledge into action by adding a footer to your website that includes your name and current year. On top of that, we’ll add an optional front matter field you can use to hide the footer on a particular page.

Let’s start with an easy one. Your name. Add it as a new key in your config.toml. Because this is just something for this site rather than a special Hugo term, we put it under the params object:

/config.toml
[params]
name = 'Simba'

Now let’s create the partial. Add footer.html to your layout partials directory with the following:

/layouts/partials/footer.html
{{ with .Params.hide_footer }}
  <!-- No footer here! -->
{{ else }}
  <footer>
    Website made by {{ .Site.Params.name }} in {{ now.Year }}
  </footer>
{{ end }}

And finally call the partial before </body> in the baseof.html layout:

/layouts/_default/baseof.html
{{ partial "footer.html" . }}

To check the hide_footer front matter is working, let’s turn the footer off on your about.md page by adding this to the front matter:

/content/about.md
hide_footer: true

Run hugo serve and look at your site in the browser. The home page has the footer and the about page doesn’t.

What’s next?

Next, we’ll explore creating a blog in Hugo and put our new Hugo templating knowledge to the test.