The dot (.) and the dollar ($) in context

Preamble and Background Story

Most of this thread was originally posted here. Another forum member suggested that I cut out my little “ah-ha” moment from my original support request thread and publish it to help others understand Hugo Context a bit better, with special attention to the use of the . “dot” and $ “dollar” (not to be mistaken for the dollar sign used in variable assignments in templates, {{ $someVar := "some text" }}.

I had a hard time understanding this subject until:

  1. I viewed a video called, “A Crash Course on Go Templates” (link follows) - the video is 20-ish minutes but is well explained.
  2. Took my time to read through the Golang documentation for the text/template package that Hugo uses for handling template parsing and variable injection into templates. This documentation is about a 10-30 minute read (depending upon your degree of programming experience and experience with template languages in other languages/frameworks).
    • PS: A side benefit to reading the text/template package documentation I link to above is that it also explains the use of the “-” dash within “{{}}” curly braces like so: {{- /* template action and pipeline are in here */ -}}. Gist: they tell the Go template parser to trim whitespace from either/both before/after the template “action/command/pipeline”.
    • PPS: The terms I mention in the previous point, “action”, “command” and “pipeline” are critical to understanding how Go (and therefore Hugo) templates function. Again, I highly recommend you read the text/template documentation page linked to above.

Up until now, I simply didn’t understand Hugo templates and the felt a bit like obscure magic to me. I thought that templates are a Hugo construct (yeah - post-facto, I realise that the Hugo documentation is VERY clear about the fact that Hugo uses the html/template and text/template packages as stated on the "Templating page in the Templates section in the documentation website). I can’t stress this enough but, just one last time (cause I too kept tripping up on the syntax used within the {{}} double-curly-braces in templates), I fervently and strongly suggest that anyone new to Hugo (even if you just simply want to get a micro-website up and running in minutes) go over the two resources listed above.

Alright… on to the actual tip/trick post content…


What are the . (dot) and $ (dollar) symbols used for in Hugo Templates?

BOTH . and $ (NOTE: just $, the dollar sign on its own and not $someVar) refer to the context variable that is passed into a given template. The difference is, the . can change what it’s pointing/referring to within a template based upon whether it is being used in EITHER a with or range “action”. For example, the value that . is pointing to can change within with and range template actions. On the other hand, the $ symbol ALWAYS refers to the ORIGINAL context that was passed into a template and it never changes.

Examples:

file: layouts/_default/baseof.html has calls a “partial” with the file name, “partials/some-partial.html” like so:

{{- /* file: layouts/_default/baseof.html */ -}}
{{ $myFullName := slice "Abraa" "Cadabra" "Dobrinda"  }}
{{ partial "some-partial.html" $myFullName }}

then, within partials/some-partial.html

{{- /* `.` refers to the slice, `$myFullName` that was passed into the partial template. */ -}}
{{ delimit . " " }}<br>{{- /* Outputs "Abraa Cadabra Dobrinda"  */ -}}

<!-- `$` ALSO refers to the slice, `$myFullName` that was passed into the partial template.  */ -}}
{{ delimit $ " " }}<br>{{- /* Outputs the same as `.` "Abraa Cadabra Dobrinda"  */ -}}

{{ range . }}
  {{- /*
    In here, the `.` is referring to each individual element that the slice $myFullName has in it.
    Thus, it will render "Abraa" then "Cadabra" then "Dobrinda" individually. NOTE: here, the `.` "dot"
    context IS NO LONGER A SLICE and thus, cannot be used with the "collections.Delimit" function.
  */ -}}
  {{ . }}<br>
  {{- /*
    Conversely, the `$` STILL refers to the original/"root level context" that was passed in, namely:
    $myFullName. Thus, it will render "Abraa Cadabra Dobrinda" as a full string for every iteration
    of the range's loop.
  */ -}}
  {{ delimit $ " " }}<br>
{{ end}}

So the total output of of layouts/some-partial.html should look something like this:

Abraa Cadabra Dobrinda<br>

Abraa Cadabra Dobrinda<br>

Abraa<br>
Abraa Cadabra Dobrinda<br>
Cadabra<br>
Abraa Cadabra Dobrinda<br>
Dobrinda<br>
Abraa Cadabra Dobrinda<br>

Cheers!

4 Likes

Thanks - but maybe a more concise title would make grasping the topic easier

1 Like

This helped, thank you @anandkp !

1 Like