Advanced Hugo tips

It's hard sometimes to find what is really important. Here are some useful examples you will need to create a good Hugo site. You will find related files in vendor/Andygrond/hugonette/doc/hugo folder of the Hugonette project. You can also download it from GitHub.

Site config

By default /config.toml or /config.yaml is a project configuration file. But more convenient is to use /config folder. Define there your environments:

  • development is for Hugo web server: hugo server

  • staging is for local generation to Hugonette project: hugo -e staging

  • _default is for production ready generation: hugo

In the exaple files you will find debug variable definition, which is used below.

Sass CSS extension

All .scss files gather in /assets folder. Assuming you use main.scss as the main file, add following code to the partials/head.html

{{- if .Site.Params.debug }}
  {{- $options := (dict "targetPath" "styles/bundle.css" "enableSourceMap" true ) }}
  {{- $styles := resources.Get "main.scss" | toCSS $options -}}
  <link rel="stylesheet" href="{{ $styles.Permalink }}" media="screen">
{{- else }}
  {{- $options := (dict "targetPath" "styles/bundle.css" "outputStyle" "compressed" ) }}
  {{- $styles := resources.Get "main.scss" | toCSS $options | minify | fingerprint -}}
  <link rel="stylesheet" href="{{ $styles.Permalink }}" media="screen">
{{- end -}}

This configuration code prepares CSS file with SourceMap for debugging, or compresses it for production, and adds fingerprint to avoid using old version from cache.

Please be aware: if you want to customize any .scss file, you must move from theme to project not only this file, but also a file which contains its @import declaration.

JS library

List all needed JavaScript libraries in the configuration /config/_default/params.yaml Move the files to /assets/js folder. Use this code to place all .js in the partial js.html

{{ $js := slice }}
{{ range .Site.Params.scripts }}
  {{ $js = $js | append (resources.Get . ) }}
{{- end }}

{{ if .Site.Params.debug }}
  {{ range $js }}
<script src="{{ .RelPermalink }}"></script>
  {{ end }}
{{ else }}
  {{ $js = $js | resources.Concat "js/bundle.js" | minify | fingerprint "md5" }}
<script src="{{ $js.RelPermalink }}"></script>
{{ end }}

The code appends all files into the $js array and next does the right action according to debug variable. In this example, for debugging purposes every file will be published in separate <script> line. For production all files are packed in one file, minified and fingerprinted.

You can manage a menu by JavaScript, Latte template or Hugo. Any way has its own pros and cons. You can even mix the techniques to achieve what you need. Now quick tutorial for Hugo.

Define menu variables in /config/_default/params.yaml

menu:
  -
    id: menu1
    name: Menu 1
    icon: icon1
    submenu:
      - 
        id: submenu3
        name: Submenu 3
        link: app/menu3
      -
        id: submenu4
        name: Submenu 4
        link: app/menu4
  -
    id: menu2
    name: Menu 2
    icon: menu2.png
    link: app/menu2

You should define native menu ID and/or submenu ID in the front matter of every page.

menu: menu1
submenu: submenu4

Then refer to this data in your partial:

{{ $id := .Params.menu }}
{{ $subid := .Params.submenu }}
<ul>
{{ range .Site.Params.menu }}
  <li{{ if eq .id $id }} class="active"{{end}}>
  {{ if .submenu }}
    ...
  {{ else }}
    ...
  {{ end }}
  </li>
{{ end }}
</ul>

Last updated