hugo
hugo copied to clipboard
Improve eq operator in where function
Use case 1: find all pages where tags equals ['foo']
.
Use case 2: find all pages where tags equals ['foo','bar']
.
This is not possible today. You can find all pages where these tags intersect a provided slice, but you cannot compare slices with the eq
operator.
The eq
operator does work if your front matter is a scalar, e.g.,
title = 'something 1`
tags = 'foo'
But you can't do this:
title = 'something 2`
tags = ['foo']
You should be able to get both of the pages above with:
{{ where .Pages "Params.tags" eq "foo" }} OR
{{ where .Pages "Params.tags" eq "foo" (slice "foo"}}
Use case 1: find all pages where tags equals ['foo']. Use case 2: find all pages where tags equals ['foo','bar'].
The above is rather technical use cases ...
I can understand if you want to find all pages tagged with foo
, but finding all pages which has the tags foo
and bar
and only those, that's not a use case I have seen.
Note that Go cannot compare slices directly, so it would be a fairly costly operation if implemented.
finding all pages which has the tags foo and bar and only those, that's not a use case I have seen
I'm fine with with limiting to one tag. The specific example is:
content/
├── publications/
│ ├── publication-1.md <-- authors = ['John', 'Richard', 'Harold']
│ ├── publication-2.md <-- authors = ['John', 'Richard']
│ └── publication-3.md <-- authors = ['John']
└── _index.md
Find all publications where John is the only author. (common) Find all publications where John and Richard are the only authors. (less common)
Go 1.21 introduced the slices package which contains https://pkg.go.dev/slices#Equal.
Go 1.21 introduced the slices package which contains https://pkg.go.dev/slices#Equal.
The functional part of this has never been the challenge. If you look at that implementation you will find a ... loop.
Understood. Will stick with...
{{ $p := where site.RegularPages "Params.tags" "intersect" (slice "a" "b") }}
{{ range $p }}
{{ if eq (len .Params.tags) 2 }}
<h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ end }}
{{ end }}
To be clear:
tags = ['foo', 'bar']
{{ where .Pages "Params.tags" eq (slice "foo" "bar" }}
Would be cheapish to implement with strict ordering (['foo', 'bar'] != ['bar', 'foo']), but I'm not sure how useful that would be.
I agree that strict ordering limits its usage; not sure I'd pursue it.