Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f5fce93

Browse files
bepclaude
andcommitted
tpl/collections: Honor the Eqer interface in where comparisons
The where function previously fell through to a no-op when comparing two values whose kinds were not handled by the primitive type switches (e.g. two Page interface values). This made `where pages "Parent" $page` return an empty list, while the equivalent `range pages` + `if eq` worked. Use compare.Eqer for equality operators when either side implements it, matching the behavior of the eq/ne template funcs. Fixes #14777 Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
1 parent 52123ae commit f5fce93

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

tpl/collections/collections_integration_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,51 @@ disableKinds = ['rss','sitemap', 'taxonomy', 'term', 'page']
289289
b.AssertFileContentExact("public/index.html", "0: /a3_b1.html\n\n1: /b2.html\n\n2: /a1.html\n\n3: /a2.html\n$")
290290
}
291291

292+
// Issue 14777.
293+
func TestWhereWithPageEqualityIssue14777(t *testing.T) {
294+
t.Parallel()
295+
296+
files := `
297+
-- hugo.toml --
298+
baseURL = 'http://example.com/'
299+
disableKinds = ['rss','sitemap','taxonomy','term']
300+
-- content/s1/_index.md --
301+
---
302+
title: S1
303+
---
304+
-- content/s1/p1.md --
305+
---
306+
title: P1
307+
---
308+
-- content/s1/p2.md --
309+
---
310+
title: P2
311+
---
312+
-- content/s2/_index.md --
313+
---
314+
title: S2
315+
---
316+
-- content/s2/p3.md --
317+
---
318+
title: P3
319+
---
320+
-- layouts/section.html --
321+
{{ $page := . }}
322+
WhereEq: {{ range where site.AllPages "Parent" "eq" $page }}{{ .Title }}|{{ end }}$
323+
WhereDefault: {{ range where site.AllPages "Parent" $page }}{{ .Title }}|{{ end }}$
324+
RangeIf: {{ range site.AllPages }}{{ if eq .Parent $page }}{{ .Title }}|{{ end }}{{ end }}$
325+
WhereNe: {{ range where site.AllPages "Parent" "ne" $page }}{{ .Title }}|{{ end }}$
326+
`
327+
328+
b := hugolib.Test(t, files)
329+
330+
b.AssertFileContent("public/s1/index.html",
331+
"WhereEq: P1|P2|$",
332+
"WhereDefault: P1|P2|$",
333+
"RangeIf: P1|P2|$",
334+
)
335+
}
336+
292337
// Issue 13621.
293338
func TestWhereNotInEmptySlice(t *testing.T) {
294339
t.Parallel()

tpl/collections/where.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/gohugoio/hugo/common/hmaps"
2424
"github.com/gohugoio/hugo/common/hreflect"
2525
"github.com/gohugoio/hugo/common/hstrings"
26+
"github.com/gohugoio/hugo/compare"
2627
)
2728

2829
// Where returns a filtered subset of collection c.
@@ -85,6 +86,16 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
8586
return false, nil
8687
}
8788

89+
switch op {
90+
case "", "=", "==", "eq", "!=", "<>", "ne":
91+
if eq, ok := tryEq(v, mv); ok {
92+
if op == "!=" || op == "<>" || op == "ne" {
93+
return !eq, nil
94+
}
95+
return eq, nil
96+
}
97+
}
98+
8899
var ivp, imvp *int64
89100
var fvp, fmvp *float64
90101
var svp, smvp *string
@@ -690,6 +701,23 @@ func (ns *Namespace) checkWhereMap(ctxv, seqv, kv, mv reflect.Value, path []stri
690701

691702
// toString returns the string value if possible, "" if not.
692703

704+
// tryEq returns the equality of v and mv via the compare.Eqer interface
705+
// if either side implements it. The second return value reports whether
706+
// such a comparison was possible.
707+
func tryEq(v, mv reflect.Value) (bool, bool) {
708+
if !v.CanInterface() || !mv.CanInterface() {
709+
return false, false
710+
}
711+
vi, mvi := v.Interface(), mv.Interface()
712+
if e, ok := vi.(compare.Eqer); ok {
713+
return e.Eq(mvi), true
714+
}
715+
if e, ok := mvi.(compare.Eqer); ok {
716+
return e.Eq(vi), true
717+
}
718+
return false, false
719+
}
720+
693721
func (ns *Namespace) toTimeUnix(v reflect.Value) int64 {
694722
t, ok := hreflect.AsTime(v, ns.loc)
695723
if !ok {

0 commit comments

Comments
 (0)