Complex Where Filter (using and, or, not)

Hi, I’ve started using Hugo and I like it very much. I’m trying to write some complex filter to build dynamic lists based on page params but I can’t figure out how to write it. I see Where filter but not a way to build some like

“Filter Pages Where type is A and params are (A=v1 AND (B=v2 OR C = v3))”

Is it possible?

thanks a lot

1 Like

Yes, you can nest your where statements…

1 Like

Thanks a lot for your answer! Where can I find an example,it would be wonderful!

Use search of this forum “range where”.

1 Like

Not sure if the last OR is possible, but the concept is this:

{{ range where (where .Site.Pages "Params.a" "v1")  "Params.b" "v2"  }}

@tatsushid has better grip on this.

2 Likes

Currently, we’ve intersect as template function which is equivalent to AND in set theory. OR could be elegantly implemented with a union template function.

2 Likes

How would you use intersect for

"Params.a" "v1" AND  "Params.b" "v2"
1 Like

If the purpose is not making a filtered list but just iterating, the easiest way is

{{range where .Site.Pages "Params.a" "v1"}}
{{if or (eq .Param.b v2) (eq .Param.c v3)}}
do something
{{end}}
{{end}}

Now where doesn’t implement nested condition and the basic concept is the one @bep mentioned above, using multiple where clauses.

3 Likes

I had the following code in mind:

{{ $v1 := where .Site.Pages "Params.a" "v1" }}
{{ $v2 := where .Site.Pages "Params.b" "v2" }}

{{ $filtered := $v1 | intersect $v2 }}
2 Likes

@bep to do the same for OR I would propose to add a union template function.

2 Likes

I submitted a pull request to add this function:

https://github.com/spf13/hugo/pull/3168

2 Likes

Reading the intersect doc, I now see that it is not does not support Pages – I guess the original use case was tags, i.e. string slices.

You will love this PR:

2 Likes

Hello, i have strange behavior trying to union .Pages and .Sections when one of the two is empty
{{ $pages := .Pages | union .Sections }}

.Pages.Len > 1
.Sections.Len = 0 (empty)

Then $pages.len = 0 :frowning:

My current workaround is

{{ .Scratch.Set "pages" .Pages }}
{{ if .Sections}}
   {{ .Scratch.Set "pages" (.Pages | union .Sections) }}
{{end}}
{{ $pages := (.Scratch.Get "pages") }}

@vjeantet that sounds like a bug, could you create a GH issue? (I’m guessing here, but you could try to turn the param order around and see if that helps.

issue created here : https://github.com/gohugoio/hugo/issues/3686

If i turn the param order i have the same bug when .Pages is empty.

It always occurs when last union’s param is empty.

Yea, a stupid bug; I have fixed it in master.

1 Like