Hugo: How to use maps

Date: 2020-01-12 | hugo | map | dict |

problem

I'm kinda new to Hugo and I'm trying to do an operation that involves inserting and iterating over a dict. I've been looking around and there seems to be some documentaiton but it's kinda fragmented all over the place. What are the basics of creating, populating, and iterating over a map?

solution

Okay so I just went through this issue while attempting to create a stats page for my sites in (which is now live if you wanna take a look). Below I'll list what I learned about using maps in Hugo and some practical examples so that your journey might be a bit less annoying.

what are maps

  • a map is basically just a dict in many other languages (I think maps are the same term they use in Golang which Hugo is built with so that's why they chose it)
  • At its core it's just a key:value store - You store each value with a given key and then you can access that value by providing the map that same key, like myMap["color"] = "red" or myMap["age"] = 25

instantiating a map in Hugo

You can't really instantiate a map in Hugo - at least not an empty one. Instead you create the map as soon as you need it. This is kind of annoying if you're used to programming in other languages but does provide a useful feature of being able to check if a map is empty or not via an if statement, like this:

{{ if $myMap }}
    <!-- $myMap has stuff in it! -->
{{ else }}
    <!-- $myMap is empty =(( -->
{{ end }}

So to create a map, really you need to insert into a map, which I'll go over below:

inserting a value into a map

Because you can't really instantiate a map, you can't easily insert directly into a map. To get around this, Hugo has a built in on Scratch (kind of this weird metaprogramming canvas / scoping thing that talking about is out of scope for this post) called SetInMap.

SetInMap's definition takes in 3 things:

  • MAPNAME - the name of the map you're trying to insert into, you can think of this kind of like the map variable name you might use in another language
  • KEY - the name of the key you're going to set as the index for your value
  • VALUE - the value you're trying to store

It's then called as:

{{ Scratch.SetInMap "MAPNAME" "KEY" VALUE }}

Note that the MAPNAME and KEY parameters takes in strings, so you can pass in variables that hold strings instead of the strings directly. The VALUE parameter, I think, can be anything you wish though I've only tried it with ints and strings. I usually store the MAPNAME in a variable to make things easier on me and avoid typos which cause syntactical / semantic errors.

So let's go over a code example. If I want to store the key value pairs ("color", "red") and ("age", 25) I can do the following:

{{ $scratch := newScratch }}
{{ $mapName := "exampleMap" }}
{{ $scratch.SetInMap $mapName "color" "red" }}
{{ $scratch.SetInMap $mapName "age" 25 }}

Boom, we've set things in a map. That's cool, but not super useful until we can access those in some way. Let's go over that next.

getting values from a map

There are a few ways to get our values from a map:

  • Scratch.Get MAPNAME - Get the map
  • Scratch.GetSortedMapValues MAPNAME - Get the map, sorted by keys

So if I wanted to iterate over my map, I could do something like this (assuming I had already insterted things into it):

{{ range $k, $v := ($scratch.Get $mapName)}}
    Key: {{ $k }}
    Value: {{ $v }}
{{ end }}

fin

That's it! If there's more you want to know about maps and their usage in Hugo, comment below and I'll look to add those sections here.

Want more like this?

The best / easiest way to support my work is by subscribing for future updates and sharing with your network.