Mind is Software

Ying’s thoughts about software and business

Hugo Note

Hugo is a static website generator writting in Go (Golang). It can be used for a blog website, a documentation site, a landing page. This is a study note based on the official Hugo doc and the Youtube Hugo tutorial.

1 Overview

1.1 Features

Hugo is fast at building static pages (less than 1ms per page). It is cross platform and has good theming support.

For site organization, it proivdes customizable URLs, taxonomies including categories and tags, content sorting, automatic TOC, dynamic menu and permalink pattern.

It supports multiple content format including multiple markdown variants. It provides content customization by configuration. It generates content summaries automatically.

It integrates with Disqus, Google Analytics, RSS, multiple HTML templates, and syntax highlighting powerered by Pygments.

1.2 File Structure

Hugo has the following files/folders structure.

  • archetypes/: it has the templates used to create new pages. A template defines a set of front matter fields.
  • config.toml: the configuration file.
  • content/: all content for your website. The content has different sections – a section represents a content typat that has its own directory under the content/ directory.
  • data/: it stores configuration files or data templtes that pull from dynamic content.
  • layouts/: store view templates for all content types. View templates include list pages, homepage, taxonomy templates, partials, and single page templates.
  • static/: this stores all static assets such as images, CSS, JavaScript, etc. All files in this folder are copied over as-is.

1.3 Configuration

Hugo can read configuration from a configuration file or from enviornment variables. You can also configure the builtin markdown engine.

1.4 Theme

A theme consists of templates and static assets. Hugo uses layout to manage different content types. Archetypes are used to scaffold new file with preconfigured front matter for a specific content. You can have an arthetype for a section type (for example archetypes/posts.md) and use a default (archetypes/default.md) for content types without a specific arthetype.

2 Content Management

There are two ways to display content in Hugo: a single piece (single.html) of content and a list of content items (list.html). Partial templates can be used to create the final templates. The default single view template is located at layouts/_default/single.html and the default list view template is located at layouts/_default/list.html.

There is a list view for the home page, two default taxonomy types (categories, tags), each content type (the top level folders under content/). Other content uses the single page view.

2.1 Content Organization

The top level folders inside content/ are special because Hugo use them as content types (sections) to determine layout etc. A content type can have a unique set of metadata, customized template and customized archetypes. A section represents a type. To define a new content type, you define the templates and archetype unique to your new content type, or Hugo will use default.

A content’s type is determined by its location in content. However the content type can be specified in the front matter. Finally, a complete URL can be provided to overide the default destination.

Sections can be nested. The URL reflects the content structure and the same structure is used to organize the rendered site. Each filename (without the entension) is used in the destination URL as the tail part. You can define a slug to replace the filename in the destination.

The _index.md is special in Hugo that it lets you to add front matter and content to your list templates. Usually you keep one _index.md for homepage and one for each section, taxonomies, and taxonomy terms. Use {{ .Content }} in your template to show the _index.md content. Except the home page and the top level sections under content/, you need a content file _index.md to have a list page view for the nested section.

2.2 Front Matters

Hugo supports three front matter formats: TOML (+++), YAML (---), and JSON ({}).

Hugo has a set of predefined front matter variables, below are some common ones:

  • date: the datetime the content was created.
  • description: the content description.
  • draft: the draft state.
  • expiryDate: the expiration datetime.
  • IsCJKLanguage: ture/false to determine summary and word count.
  • keywords: the meta keywords for the content.
  • layout: the layout name.
  • lastmod: the last modified datetime.
  • linkTitle: the link title to the content.
  • publishDate: the date to publish the content.
  • slug: the tail of the output URL.
  • weight: the weight used in content list ordering.

User-defined fields are palced into a single .Params variable.

2.3 Variables

Hugo’s templates use content variables to generate views. There are several types of variables.

  • Site variables: most are defined in site’s configuraiton. Hugo provides a number of build-in variables for convenient access to site variables. For example, use .Langugage in a page to access .Site.Language.
  • Page variables: most are defined in a content file’s front matter, derived from the content file location, or extracted from the content body.

2.4 Taxonomies

Hugo use taxonomy to classify content. A taxonomy is a categorization that can be used to classify content. A taxonomy has many terms (keys). The pages assciated with a term are values of the term.

Hugo comes with two default taxonomies: tags and categeories. To create a new taxonomy, add a line of singular: "plural" to the taxonomies in configuraiton file. For example, series: "series". Then assign content to a taxonomy in its front matter.

2.5 Menus

Hugo has a menu system that consists of a site menu variable (.Site.Menus is a named array of menu entries) used by any number of menu templates. Menu variables can be defined via front matter key menu and site config file key menu.[menu-name].

Hugo allows you to create a section menu quickly with a simple config. To add other menus, you need manully create menu entries. There are three ways to create menus:

2.5.1 Enable Section Menu

Hugo makes it easy to display a section menu. First, configure sectionPagesMenu = "main" in your site config. The “main” could be any name that will be used in your menu templates. Then, create your menu template and use it in your layout template file:

{{ range .Site.Menus.main }}
    <a href="{{ .URL }}" title="{{ .Title }}">{{ .Name }}</a>
{{ end }}

2.5.2 Add Menu Entry in Front Matter

First you can add a content to menu by defining menu entries in the front matter of a content page. The menu entry points to the page it is defined.

Then you can use the menu varaibles in your menu template. The templae access to the .Page variable from a menu entry.

2.5.3 Add Menu Entry in Site Config

If you use site config method, you need to specify the menu entry name, url, and other values. Once defined, you can use the menu entry in a menu template.

2.6 Summaries

By default, Hugo automatically takes the first 70 words of your content as its summary and stores it into the .Summary page variable. Alternatively, you add <!--more--> summary divider where you want to split the article.

2.7 Multilingual Mode

Hugo supports side-by-side multiple languages by settings in languages. Taxonomies and blackfriday can also be set per language. To support multilingual themes, construct URLs using relLangURL or absLangURL template functions or prfiex path with {{ .LanguagePrefix}}.

3 Templates

3.1 Template Language

Hugo uses Go’s html/template and text/template as its template language.

The Go’s templates are HTML files with the addition of variables and functions accessed within {{ }}. Each template is passed a Page as its data object. Following are some often-used syntax:

  • To access a variable, use {{ foo }}.
  • To call a function, use {{ add 1 2 }}.
  • To define a variable, use {{ $foo := 23 }}.
  • Use {{ range array }} ... {{ end }} to access array elements.
  • Use {{ if }}, {{ else }}, {{ with }} (if and rebind the content . within its scope, skip the block if the variable is absent) for conditional process. You can use and, or, not, | (pipe), . ( current content), $ (the global context).
  • Use {{- foo -}} to trim whitespace.

3.2 Template Lookup Order

Hugo searches for a layout for a given page in a predefined order, taking into account of the kind (one of home, section, taxonomy, and taxonomyTerm), output format, language, layout, type (if not set, default is page), section.

Hugo use project’s layouts/ folder before a theme’s layouts/ folder.

For home page, the filename could be index, home, list.

3.3 Base Template and Blocks

Hugo let you use base template to define outer shell of your master templates. If defined, all templates or templates of a specific type will be created from the base template of that type. The name and localtion are used to find the base template: /layouts/[section/]<TYPE>-baseof.html, /layouts/[section/]<TYPE>/baseof.html, /layouts/[{section|_default}/baseof.html, and etc. For example, /layouts/_default/baseof.html will be the base template for all content templates.

In base template, use {{ block "block-name" . }} to include a block defined by other layout templates. Use {{ define "block-name" }} ... {{ end }} to define a block in a layout template.

Base template and blocks give you a flexible way to create your templates.

3.4 Different Templates

3.4.1 List Page Template

A list page renders alist of content in a single HTML page. List content includes taxonomy terms, exonomy list, RSS, section list.

Default section list is sectoin.html while default taxonomy list is taxonomy.html. Both can use list.html as the terminating default.

The _index.md content can be access in a section file by using {{ .Content }}. All variables defined in its front matter are also available as page variables.

Hugo can render list based on weight, date, link title, length, title, or even paramters. It can render a specific content view using {{ .Render "view" }}.

It can group pages by section, type, date, etc. It can filer and limite the number of list elements.

3.4.2 Homepage Template

The homepage has a unique template. It is also the only required template for building a site.

The homepage can accept content and front matter from an _index.md file. It can access to all site conent via .Data.Pages.

3.4.3 Section Template

At the top section level, use .GetPage kind value to get the index page of a given kind and kind value.

3.4.4 Taxonomy Templates

Taxonomyt emplating includes taxonomy list template, taxonomy term template, and using taxonomies in your single page templates.

Taxonomies for content are defined in front matter. They are accessed using .Params.tags or .Params.categories.

3.4.5 Single Page Templates

Hugo renders every markdown file with a corresponding single page template.

3.4.6 Content View Templates

A content may have different views such as a list view or a summary view. Hugo also supports default content view template defined in layouts/_default/ folder.

3.4.7 Other Templates

There are other templates such as data templates, partial templates, shortcode templates, 404 page, pagination, sitemap template, robots.txt, and internal templates (Google Anayltics, Disqus, etc.)


Share