Hugo uses Go’s html/template and text/template libraries as the basis for the templating.
Hugo’s introduction to templating provide a brief outline on Go’s templates which are HTML files with the addition of variables and functions which are accessible within {{ }}
.
Content templates can be used to generate new pages quickly. Different templates can be used for different content sections of the website.
Markdown templates are usually kept in the archetypes
folder of the website. Archetypes are templates used when creating new content.
An archetype is basically a model or pattern that is used as the basis for other content of the same type. A default.md
archetype is created when a site is created using hugo new site
command.
You can have archetypes for each type of content. For example I have archetypes for projects
and posts
. These will be used as the basis for creating a new project or blog post when used with the hugo new
command. hugo new posts/
followed by the blog post name will use the posts.md
archetype while
hugo new projects/
followed by the project name will use the projects.md
archetype.
The basic syntax for templates includes the following sections. I am not going to reproduce the documentation here, just note some relevant sections I have used so far.
Accessing a predefined variable
-
A predefined variable could be a variable already existing in the current scope or a custom variable. (Custom variables are prefixed with
$
). An example of accessing a variables:{{ .Title }}
-
Parameters for functions are separated by spaces with the following general syntax:
{{ FUNCTION ARG1 ARG2 .. }}
-
Methods and fields are accessed via dot notation. For example use
{{ .Params.bar }}
to access the Page Parameterbar
defined in a piece of content’s front matter. -
Parentheses can be used to group items together.
Variables
-
Each Go template gets a data object.
-
In Hugo each template is passed a
Page
(which is the default scope of a template).{{ .Title }}
refers to theTitle
element in the current scope. -
A variable is accessed by referencing the variable name
<title>{{ .Title }}</title>
-
Values can also be defined in custom variables and accessed or referenced later.
{{ $address := "123 Main St." }}
{{ $address }}
Functions
- Go Templates have a few basic functions but these can be extended. Hugo template functions provide additional functionality for building websites.
- Functions are called using their name followed by parameters separated by spaces.
Includes
- When including another template you need to pass in the data it needs to access.
- A trailing dot
.
is used to pass along the current context. - The templates location always starts at the
layouts/
directory within Hugo.
`Partial
The partial function is used to include partial templates using the syntax
{{ partial "<PATH>/<PARTIAL>.<EXTENSION>" . }}>
.
Template
The template
function is used for calling internal internal templates using {{ template "_internal/<TEMPLATE>.<EXTENSION>" . }}.
. The list of internal templates is here. It includes the pagination
template I use for blog posts as well as templates for Google Analytics, Disqus, Open Graph, Twitter Cards.
Logic
Go templates provide basic iteration and conditional logic.
Iterations - range
.
- Iteration using
range
to iterate over a map, array or slice. Eachrange
statement is closed with an{{ end }}
. The documentation provides several examples with the first being using context.
here:
{{ range $array }}
{{ . }}
{{ end }}
Conditionals using if
, else
, with
, or
, and and
.
- Each conditional statement is closed with an
{{ end }}
. with
is used to say if something exists then do something.
Here is the first example from Hugo’s introduction.
{{ with .Params.title }}
<h4>{{ . }}</h4>
{{ end }}
Pipes for chaining function calls.
- used to stack actions one after the other like Unix pipes.
- pipes can only work with a single value
Context (aka “the dot”)
{{ . }}
always refers to the current context- in the top level of the template the current context refers to the data set made available to it
- inside an iteration the current context refers to the value of the current item in the loop and not the data made available to the entire page.
There are a few examples listed of what to do if you need to access page-level data such as page params set in front matter including:
- Defining a variable independent of the context
- Using
$
to access the Global context.$
is set to the starting value of.
by default so you have access to the global context from anywhere. For example$.Site.Title
to grab a.Site.Title
from the global context.
Whitespace
- Hyphens
-
are used to trim whitespace from a Go tag. Include a-
immediately beside the{{
or}}
delimiter.
Comments
- Go template support
{{/*
and*/}}
to open and close a comment block. - Do not use HTML comments
<!--comment-->
to comment out Go template code as the content will still be evaluated. - An example is provided of how to construct HTML comments from a template by piping
printf
tosafeHTML
. For example
{{ printf "<!-- Our website is named: %s -->" .Site.Title | safeHTML }}
Hugo Parameters
Hugo allows you to pass values to a template layer through the site configuration for site-wide values or through the metadata of each specific piece of content using front matter.
Content (Page
) Parameters
Variables can be provided in individual content’s front matter that can be used by templates.
An example is shown in the docs where a table of contents partial template (layouts/partials/toc.html
) will not be rendered if a variable notoc
in the front matter of a content is set to true.
Site Configuration Parameters
Site level parameters can be defined in the sites configuration file and are globally available in the templates.
Hugo has some Lookup order rules used for looking up the layout to use for a particular page, starting from the most specific. The following is the order of parameters:
- The page
Kind
- Layout can be set in front matter
- Output format
- Language
- Type
- Section
Layouts can be in the project’s or the themes layout folder with the most specific layout chosen. The table here outlines the lookup order to use for various types of pages such as the single page template in a “posts” section, the base template to use for single pages in “posts” section, the Home page, Section pages, taxonomy pages, term pages etc.
The base template lookup order closely follows that of the template it applies to.
layouts/_default/base_of.html
.
This is the shell from which all pages are rendered unless another *baseof.html
template is specified that is closer to the beginning of the lookup order.
- The base template is called
baseof.html
underlayouts/_default/
(usually under the theme being used).
Base Templates and Blocks
Base and block constructs are used to define the outer shell of the master templates.
List pages
A list page template is a template used to render multiple pieces of content in a single HTML page. (The homepage has its own dedicated template.)
Hugo uses list templates on any output HTML page where content is usually listed such as Taxonomy terms pages, taxonomy list pages, Section list pages and RSS.
Adding content and front matter to list pages.
Everything in Hugo is a Page
and therefore list pages and the homepage can have associated content files (_index.md
) containing metadata (front matter) and content.
All _index.md
content files will render according to a list template and not according to single page templates.
The list template can use front matter (such as title, dates etc) as well as markdown content using {{.Content}}
.
You can also have List Pages Without _index.md. If Hugo doesn’t find an _index.md
file in the respective content section when rendering a list template, the page will still be created but with no {{.Content}}
and only default values for the .Title
etc.
Note - Hugo pluralises list titles.
I will come back to this. There are many partial templates that can be used in list and page templates. Also shortcode templates, menu templates, pagination templates