The question is clear. We need to pass variables or arguments in Hugo’s partials. We usually use only the dot when calling partials. {{ partial "foo.html" . }}. The dot means the current page’s context. All it’s variables like .Title, .Permalink, .Content and all others will pass on with that dot.
Sometimes, we need to send more. For example, I’ve got a partial named generate_button.html and pass the href, name, and color variables. None of them are related to page content. To pass these arguments to the “partial” we need to use a dictionary instead of passing the dot.
{{ partial "helpers/generate_button.html" (dict "href" "/tags" "name" "Display by Tags" "theme" "paper-theme")}}
In this case, I can’t access any of the variables of the page inside the partial. .Title won’t work. Because we didn’t pass the dot. So, we need to include the dot in our dictionary.
{{ partial "your_crazy_good_partial.html" (dict "context" . "arg1" "val1" "arg2" "val2") }}
Now, in order to access page variables from “partial”, we need to prefix the dot’s name which is “context”. .context.Title, .context.Date, etc…
There is one more way, it’s called scratch. I mentioned it before in Loops in Hugo. Basically, with scratch, we can add variables into the page’s content then pass the dot alone instead of passing a dictionary. By using Scratch, you may get more clean and elegant code.
{{ .Scratch.Set "arg1" "val1" }}
{{ partial "your_crazy_good_partial.html" . }}
With this method, we can access all the standard page variables as we normally do. We don’t need to call .context.Title to get .Title. This is a solid advantage over the dictionary method. To access our special variable, val1, we need to use {{ .Scratch.Get "arg1" }}.
Here is an example of how I used .Scratch. I wanted to use a different color theme depending on the post-card’s index in the list. So, while looping through posts I wanted to send index. This is a very common use case, “how to get index in a range?". Instead of, using the dictionary method, it can be done using “scratchpad”.
{{ .Scratch.Set "index" 0 }}
{{ range $pages }}
{{ $.Scratch.Set "index" (add ($.Scratch.Get "index") 1) }}
{{ .Scratch.Set "index" ($.Scratch.Get "index") }}
{{ partial "cards/post_card_classic.html" . }}
{{ end }}
4th line here sets the scratch variable of the page in loops' iteration. While $.Scratch indicates the top-level variable which means the main page outside of the loop. Then I can access the index variable in post_card_classic partial by calling {{.Scratch.Get "index"}}.
