From 5c7fad23a3f8631e10264aa42efafe98dbf853d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Wed, 31 Dec 2025 11:10:19 +0100 Subject: [PATCH] tpl/collections: Fix apply to work with built-in funcs like len Fixes #13418 --- tpl/collections/apply.go | 8 +++++++- tpl/collections/collections_integration_test.go | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/tpl/collections/apply.go b/tpl/collections/apply.go index 5b3cbe54d14..23c6a74976a 100644 --- a/tpl/collections/apply.go +++ b/tpl/collections/apply.go @@ -64,6 +64,8 @@ func (ns *Namespace) Apply(ctx context.Context, c any, fname string, args ...any } } +var typeOfReflectValue = reflect.TypeOf(reflect.Value{}) + func applyFnToThis(ctx context.Context, fn, this reflect.Value, args ...any) (reflect.Value, error) { num := fn.Type().NumIn() if num > 0 && hreflect.IsContextType(fn.Type().In(0)) { @@ -91,7 +93,11 @@ func applyFnToThis(ctx context.Context, fn, this reflect.Value, args ...any) (re }*/ for i := range num { - // AssignableTo reports whether xt is assignable to type targ. + // Go's built-in template funcs (e.g. len) use reflect.Value as argument type. + if fn.Type().In(i) == typeOfReflectValue && n[i].Type() != typeOfReflectValue { + n[i] = reflect.ValueOf(n[i]) + } + if xt, targ := n[i].Type(), fn.Type().In(i); !xt.AssignableTo(targ) { return reflect.ValueOf(nil), errors.New("called apply using " + xt.String() + " as type " + targ.String()) } diff --git a/tpl/collections/collections_integration_test.go b/tpl/collections/collections_integration_test.go index 1adfd5abf5c..a1a14852419 100644 --- a/tpl/collections/collections_integration_test.go +++ b/tpl/collections/collections_integration_test.go @@ -39,6 +39,21 @@ baseURL = 'http://example.com/' `) } +func TestApplyBuiltInIssue13418(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +baseURL = 'http://example.com/' +-- layouts/home.html -- +len: {{ apply (slice "hello") "len" "." }} +not: {{ apply (slice "hello") "not" "." }} +` + b := hugolib.Test(t, files) + + b.AssertFileContent("public/index.html", "len: [5]", "not: [false]") +} + // Issue 9865 func TestSortStable(t *testing.T) { t.Parallel()