How does range succeed when delimit fails with can't iterate over <nil>?

If I put params in front matter such as

[params]
  authors = [ 'First A. Author', 'Middle B. Author', 'Last M. Author' ]

and attempt to join the strings using collections.Delimit,

<p class="authorlist">{{ delimit ( .Param "authors" ) ", " " and " }}</p>

I get the error

<delimit (.Param "authors") ", " " and ">: error calling delimit: can't iterate over <nil>

The reason seems to be delimit expects []string whereas .Param "authors" is a []interface {}. If instead I use range to write

{{ $authors := slice }}
{{ range .Param "authors" }}
  {{ $authors = $authors | append . }}
{{ end }}

then delimit $authors ", " " and " works as expected. I presume range is more flexible about the type of slice, but the iteration just to assemble a string slice seems superfluous. Is there another way to think about this that makes more sense or a handy trick?

using hugo version v0.126.1+extended on arch

One of the pages rendered by the template does not contain an “authors” key in front matter.

That’s why it’s telling you that it can’t iterate over nil.

You need to code defensively.

{{ with .Param "authors"}}
  {{ delimit . ", " " and "}}
{{ end }}
1 Like

Super helpful, thanks!

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.