Tech notes

Javascript, HTML, CSS

Feb 14, 2020 | hugo development gcloud

Introduction to Hugo


Hugo is an open source static site builder. It is fast (less than a 1 sec per page), powerfull and easy to use. Hugo supports unlimited content types, tags, menus, dynamic API-driven content, and more, all without plugins.

I have chose Hugo to maintain a corporate blog for NMLStream and recently decided to switch my own blog to the Hugo as well. This article is a quick guide (mostly for myself as a reminder) with an explanation of the most common structure of Hugo projects with some snippets.

A command hugo new site <folder_path> will automatically create a new Hugo project. By default Hugo project contains the following folders and config file:

archetypes

Archetypes defines fields and default values for the frontmatter - a metadata about content (articles): date created, title, author, tags, etc. Archetypes can be default and apply to all content files, or if archetypes has a name of specific directory in content archetype will only apply to files in this directory (dir1.md applies to files in content/dir1). Archetypes -> post -> default

E.g. in this case archetype settings of the default.md will be applied only for the content/post items. Example of the default.md:

---
      title: "{{ replace .Name "-" " " | title }}"
      date: {{ .Date }}
      description: "some unique description of the article"
      tags: ["tag1", "tag2"]
      draft: true
      ---

content

Hugo defines two separate types of content: single page and list page. The layout of each page will be defined in the layout folder. Content folder itself contains only content: text,images, and frontmatter. Content can be a .md or .html. Content can be grouped logically in different folders. For example, if your site has three main sections—blog, articles, and tutorials—you will have three directories at content/blog, content/articles, and content/tutorials. Top of each content file usually contains a frontmatter defined in the archetypes. Example of the content file:

---
title: "Introduction to Hugo"
date: 2020-02-14T13:58:47-08:00
tags: ["hugo", "development", "gcloud"]
description: "Some article description"
draft: true
---

Content of the article, which may contain a html tags and style classes.

Note: if you want to use images or other static files (usually located in the static folder) you can't use {{.Site.BaseURL}} variable. You have to define full path to the file like this src="../../blog_img/file_name.png"

data

Data folder contains some website data, it can be database or simple json file. To access json file (e.g. in list.html) {{ range .Site.Data.name_of_the_json_file }} {{end}}

layouts

Layouts folder contains the layouts for the single and list pages. It can be empty if you are using specific theme and theme directory has its own defined layouts. If you add a custom layouts into the top "layouts" directory it will override existing theme.

To create custom layout in this directory create _default directory with single.html and list.html files (naming here is important!). {{.Content}} will display the content of _index.md file in the content directory. Below is an example of list.html.

<!DOCTYPE html>
  <html lang="en">
  <head>
    {{ partial "head" . }}
  </head>

  <body>
    {{ partial "header" . }}
    {{.Content}}

  <section class="main container">
    {{ range (.Paginator 10).Pages }}
    <div class="article">
      <a href="{{.Permalink}}" class="article-header">{{.Title}}</a>
      <div>
        <span>{{dateFormat "Jan 2, 2006" .Date}}</span>
        {{ if .Params.tags }} |
         {{range .Params.tags}}
           <a class="tag" href="{{ "/tags/" | relLangURL }}{{ . | urlize }}/">{{ . }}</a>
         {{end}}
        {{end}}
      </div>
      <p>{{.Description}}
        <a href="{{.Permalink}}" class="more">Read more  >></a>
      </p>
    </div>
    {{end}}

    <div class="d-flex justify-content-between">
      {{ if .Paginator.HasPrev }}
          <a href="{{ .Paginator.Prev.URL }}">  Newer Posts </a>
      {{ end }}
      {{ if .Paginator.HasNext }}
          <a href="{{ .Paginator.Next.URL }}">  Older Posts </a>
      {{ end }}
    </div>
  </section>

    {{ partial "footer" . }}
  </body>
  </html>

In layouts directory you can specify partials - part of the web pages that is identical for every page, like footer or header. {{ partial "header" . }} - usage in the list.html or single.html. Dot at the end passes the scope of the current file(e.g. to access the Title, URL or other variables). All partials files should be located in the layouts/partials folder.

static

Stores all the static content: images, CSS, JavaScript, etc. When Hugo builds your site, all assets inside your static directory are copied over as-is. A good example of using the static folder is for verifying site ownership on Google Search Console, where you want Hugo to copy over a complete HTML file without modifying its content.

themes

If you don't want to set up layouts and style them, you may want to use one of the Hugo themes whit predefined layout. All the files in this folder can be overriden if you define your own layout in the "layouts" folder.

config.toml

Hugo uses the config.toml, config.yaml, or config.json (if found in the site root) as the default site config file. The user can choose to override that default with one or more site config files using the command line --config switch.

Other components

Variables

Default Hugo variables: Title, Date, URL, etc. Custom variables can be added to the front matter. Access will look like {{ .Params.myVar }}. Examples of usage:

To style elements:<h1 style=“color: {{ .Params.color }};”> Article title</h1>

Read more about variables Hugo.io/variables

Functions

- Truncate long string to n symbols {{ truncate 10 “Very long description of some boring article}} Result: Very long …

- Arithmetic {{ add 1 5 }} Result: 6

- String concatenation {{ sub 1 5 }} Result: 15

- Singulirize/pluralize {{ singularize “dogs”}} Result dog

- Looping {{ range .Pages }} {{end}}


Back to blog