What are rules for loading data from .Site.Data?

From the example provided at Data templates | Hugo

The list of bass players can be accessed via .Site.Data.jazz.bass , a single bass player by adding the filename without the suffix, e.g. .Site.Data.jazz.bass.jacopastorius .

I don’t seem to be able to replicate the behavior implied in “by adding the filename without the suffix”. Maybe I misunderstand what it’s saying there?

Given the following source data:

/data/services/one.json

{
 "name": "one",
 "services" :
  [
    "alpha",
    "beta",
    "gamma"
  ]
}

/data/services/two.json

{
 "name": "two",
 "services" :
  [
    "delta",
    "epsilon",
    "zeta"
  ]
}

/data/services/three.json

{
 "name": "three",
 "services" :
  [
    "eta",
    "theta",
    "iota"
  ]
}

The following partial called as {{ partial "services.html" . }} correctly renders the services from all files in the /data/services/ directory:

/layouts/partials/services.html

<div>Services Partial</div>
<div>
  {{ range .Site.Data.services }}
    <div>{{ .name }}</div>
    {{ range .services }}
        <div>{{ . }}</div>
    {{ end }}
  {{ end }}
</div>

So it would seem that we should be able to append an individual filename (without extension) to limit the range to the one file

<div>Services Partial</div>
<div>
  {{ range .Site.Data.services.two }}
    <div>{{ .name }}</div>
    {{ range .services }}
        <div>{{ . }}</div>
    {{ end }}
  {{ end }}
</div>

But that breaks on can't evaluate field name in type interface

It can be made to work by wrapping the attributes in a {{ with }} context :

<div>Services Partial</div>
{{ $f := .Site.Data.services.two }}
<div>
     {{ range $f }}
        {{ with $f }}
         <div>{{ .name }}</div>
        {{ range .services }}
           <div>{{ . }}</div>
       {{ end }}
    {{ end }}
  {{ end }}
</div>

So that’s a clue but not an answer on what’s going on where the documentation says a single bass player by adding the filename without the suffix.

You are trying to range over an object, not an array.

Do this instead:

{{ with .Site.Data.services.two }}

That’s simple enough, nice!

Just to leave the breadcrumbs for the other lost children to follow:

with is a hugo function with | Hugo
which rebinds the context (.) —in this case, it puts the data loaded from the file system into the current context.

range is also a hugo function range | Hugo. which appears to also put the input collection into the current context. Is that right?

Thanks!

See https://pkg.go.dev/text/template#hdr-Actions

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