"range where ... " not working, simple "if" does

I have a collection of .json files in site/data/partners/. Sample content is:

{
  "title": "Schweizerische Eidgenossenschaft",
  "image": "/img/schweizerische-eidgenossenschaft.png",
  "link": "https://www.sem.admin.ch/",
  "type": "partner",
  "city": []
}

Note the “type” key and “partner” value. The “type” key has only a few supported values, and I want to display partners with a particular value for this key.

Displaying all the partners works, with a simple range like:

 <ul>
  {{ range $.Site.Data.partners }}
    <li>{{ .title }} : {{.type}}</li>
  {{ end }}
</ul>

That shows all the partners, as expected.

Using an “if” test in the middle also works:

<ul>
  {{ range $.Site.Data.partners }}
    {{ if eq .type "partner"}}
      <li>{{ .title }} : {{.type}}</li>
    {{ end }}
  {{ end }}
</ul>

This only shows partners where “type” equals “partner”.

From reading the “where” docs I expected that this would also work:

<ul>
  {{ range where $.Site.Data.partners "partner" "type"}}
    <li>{{ .title }} : {{.type}}</li>
  {{ end }}
</ul>

But it doesn’t – I get no output. There are no errors or warnings in the console, hugo version shows

Hugo Static Site Generator v0.58.2-253E5FDC windows/amd64 BuildDate: 2019-09-13T08:06:10Z

I’m missing something obvious, but I’m damned if I can see it…

The other way around.

 {{ range where $.Site.Data.partners "type" "partner"}}

This of this as "Where type is/equals “partner”.

Still doesn’t work (and that’s my fault for retyping the example instead of copying and pasting). I can confirm that I have:

<ul>
  {{ range where $.Site.Data.partners "type" "partner"}}
    <li>{{ .title }} : {{.type}}</li>
  {{ end }}
</ul>

Is this perhaps not working because $.Site.Data.partners is a map of maps (keyed on the title), rather than an array of maps?

short try

{{ range where $.Site.Data.partners "type" "eq" "partner"}}

Doesn’t work, unfortunately, but thanks.

My “it’s a map of maps, not an array of maps” insight appears to be correct. If I do the following:

<!-- First construct a slice of maps, one entry per partner -->
{{ $allPartners := slice}}
{{ range $.Site.Data.partners }}
  {{ $allPartners = $allPartners | append . }}
{{ end }}

<!-- Now use "where" with the slice -->
<ul>
  {{ range where $allPartners "type" "partner"}}
    <li>{{ .title }} : {{ .type }}</li>
  {{ end }}
</ul>

then I get the expected output.

Strictly speaking this is following the letter of the documentation, but it’s surprising that “where” doesn’t work with maps-of-maps. Is this worth filing a bug / feature request for?

1 Like

Hi,

The docs actually do say:

where

Filters an array to only the elements containing a matching value for a given field.

Yep. So you’d expect trying to use it with a non-array would report an error. I’ve filed https://github.com/gohugoio/hugo/issues/6358 to track this.

1 Like