Range can’t iterate over array

Environment Details

Hugo Static Site Generator v0.55.4 linux/amd64 BuildDate: 2019-04-25T10:10:44Z
GOOS="linux"
GOARCH="amd64"
GOVERSION="go1.12.2"

Error

I’m trying to create a data template to range over a JSON array in one of my ~/data files, but I’m stuck on the following error:

... execute of template failed: template: ... at <$quote>: range can't iterate over $.Site.Data.quotes.person.lines

… but what am I doing wrong to keep Hugo from iterating over what is, in fact, an array?

JSON Schema

From ~/data/quotes.json, clearly showing person.lines as an array:

{
    "person": {
        "lines": [
            "first line of trenchant prose",
            "second line",
            "don’t forget this line",
            "long-winded author",
            "last line."
        ]
    }
}

I’m referencing the person key as a front matter value in my templates and making it the context inside the partial template (the template throwing the error).

Template

<blockquote>
    {{ $quote := . }}
    {{ range (printf "$.Site.Data.quotes.%s.lines" $quote) }}            
        <span>{{ . }}</span>
    {{ end }}
</blockquote>

I don’t think it’s a context issue, since I’m able to access the $quote with the dot, as suggested by the error text. So, I’m stumped.

Please advise.

Thanks for your help.

You need to do something like:

$q := index $.Site.Data.quotes  $quote
with $q 
range .lines
end

I omitted the brackets because of laziness.

Thanks for sticking with me here, @bep.

So, I just tried this:

{{ $quote := . }}                               
{{ $q := index $.Site.Data.quotes $quote }}              
{{ with $q }}                                                       
    {{ range .lines }}                                              
        {{ . }}                                                     
    {{ end }}                                                       
{{ end }}

And the new error seems to suggest a dot context issue . . . ? (Which I’d be at a loss to rectify if I can access the variable with .)

at <$.Site.Data.quotes>: can't evaluate field Site in type string

Did I miss something?

I assume “$” is in fact a string (maybe the same as “.”?), in the context you’re using this snippet. Try using the global “site” variable instead:

{{ $q := index site.Data.quotes $quote }}

@madispe, astounding! … and strange.

I cannot imagine a future in which I would have come to that solution on my own, let alone that it would actually work.

Glad you got it working!

You might get more context (heh) from this documentation paragraph regarding contexts:

$ has special significance in your templates. $ is set to the starting value of . (“the dot”) by default.

BUT

From within the partial, $.Var is equivalent to .Var .

(source)

In your case it tried to access "your quote content as string".Site.Data.quotes, which failed obviously.

Basically just try to use the global site variable everywhere :stuck_out_tongue:

Thanks! :slight_smile: