Oskar
February 2, 2022, 9:52am
1
Assuming our normal markdown pages have a is_featured
field in the frontmatter, we can filter like this
{{ range where .Site.Pages ".Params.is_featured" true }}
… but how can you do the same with data pages? E.g. content stored in data/posts/my-post.yml
.
I tried many combinations but couldn’t make it work. What’s the proper syntax?
{{ range where .Site.Data.posts ".Params.is_featured" true }}
Try:
range where .Site.Data.posts "is_featured" true
1 Like
Oskar
February 3, 2022, 8:55am
3
Thanks, but it doesn’t return anything I’m afraid. See here:
I searched some more and found that the “Site.Data…” are technically maps — not arrays — which could explain why the where
does not work… Pretty counter-intuitive, especially since range
works fine. See:
Wouldn’t hugo want to support this feature? Maybe automagically map the maps into arrays when used together with where
?
The method used to extract the desired data depends on the data structure , and there are an infinite number of possible structures. If you share a meaningful sample of your data, perhaps we can find a way to get what you need.
Oskar
February 3, 2022, 9:59am
5
You’re right, my bad. Looks like so:
/data/spaces/test.yml
name: My title
is_featured: true
Assuming this directory structure:
data
└── spaces/
├── a.yaml
├── b.yaml
└── c.yaml
You can get a better understanding of your data structure with:
<pre>{{ jsonify (dict "indent" " ") site.Data }}</pre>
That renders this:
{
"spaces": {
"a": {
"is_featured": true,
"name": "a"
},
"b": {
"is_featured": false,
"name": "b"
},
"c": {
"is_featured": true,
"name": "c"
}
}
}
So to find the “names” that are “featured”…
{{ range site.Data.spaces }}
{{ if .is_featured }}
{{ .name }}
{{ end }}
{{ end }}
4 Likes
Oskar
February 3, 2022, 11:30am
7
Thanks so much for the detailed answer and nifty tip with jsonify
.
The nested-if solution works. How would you get the length of “featured spaces” in your example? You’d have to iterate and append into a new array, correct?
Seems useful if hugo could support maps with range where
directly. Less mental overhead if site.pages + site.data would parse the same way. Anyway, that’s a feature request.
They do parse the same way when they have the same top-level structure.
If you had created a single spaces.yaml file instead of separate files in a spaces directory:
- name: a
is_featured: true
- name: b
is_featured: false
- name: c
is_featured: true
This:
<pre>{{ jsonify (dict "indent" " ") site.Data }}</pre>
Produces this:
{
"spaces": [
{
"is_featured": true,
"name": "a"
},
{
"is_featured": false,
"name": "b"
},
{
"is_featured": true,
"name": "c"
}
]
}
And then you can do this:
{{ range where site.Data.spaces "is_featured" true }}
{{ .name }}
{{ end }}
Finally, if you have this structure:
data
└── spaces/
├── a.yaml
├── b.yaml
└── c.yaml
and if the file names should not be part of the data structure, you can wrangle the array of nested maps into an array of maps with:
{{ $temp := slice }}
{{ range site.Data.spaces }}
{{ $temp = $temp | append . }}
{{ end }}
That looks like this:
[
{
"is_featured": true,
"name": "a"
},
{
"is_featured": false,
"name": "b"
},
{
"is_featured": true,
"name": "c"
}
]
and then you can do:
{{ range where $temp "is_featured" true }}
{{ .name }}
{{ end }}
1 Like
system
Closed
February 5, 2022, 11:56am
9
This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.