diff options
author | Bjørn Erik Pedersen <[email protected]> | 2022-03-01 11:30:11 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2022-03-01 13:18:02 +0100 |
commit | 376704d382df163c7a0db066900f021ea5f7894d (patch) | |
tree | 97d09299795f58a4725d94b9b288b5c6aed64d8e /tpl | |
parent | 41b5bc9637e064f6182dd37fe3077c1582614f5b (diff) | |
download | hugo-376704d382df163c7a0db066900f021ea5f7894d.tar.gz hugo-376704d382df163c7a0db066900f021ea5f7894d.zip |
tpl/collections: Fix apply when function have Context as first arg
As introduced in `partial` and `partialCached` in Hugo 0.93.0.
Fixes #9585
Diffstat (limited to 'tpl')
-rw-r--r-- | tpl/collections/apply.go | 17 | ||||
-rw-r--r-- | tpl/collections/apply_test.go | 12 | ||||
-rw-r--r-- | tpl/collections/integration_test.go | 45 |
3 files changed, 62 insertions, 12 deletions
diff --git a/tpl/collections/apply.go b/tpl/collections/apply.go index 6eedb4b63..0833e5507 100644 --- a/tpl/collections/apply.go +++ b/tpl/collections/apply.go @@ -14,16 +14,18 @@ package collections import ( + "context" "errors" "fmt" "reflect" "strings" + "github.com/gohugoio/hugo/common/hreflect" "github.com/gohugoio/hugo/tpl" ) // Apply takes a map, array, or slice and returns a new slice with the function fname applied over it. -func (ns *Namespace) Apply(seq interface{}, fname string, args ...interface{}) (interface{}, error) { +func (ns *Namespace) Apply(ctx context.Context, seq interface{}, fname string, args ...interface{}) (interface{}, error) { if seq == nil { return make([]interface{}, 0), nil } @@ -43,15 +45,13 @@ func (ns *Namespace) Apply(seq interface{}, fname string, args ...interface{}) ( return nil, errors.New("can't find function " + fname) } - // fnv := reflect.ValueOf(fn) - switch seqv.Kind() { case reflect.Array, reflect.Slice: r := make([]interface{}, seqv.Len()) for i := 0; i < seqv.Len(); i++ { vv := seqv.Index(i) - vvv, err := applyFnToThis(fnv, vv, args...) + vvv, err := applyFnToThis(ctx, fnv, vv, args...) if err != nil { return nil, err } @@ -65,7 +65,12 @@ func (ns *Namespace) Apply(seq interface{}, fname string, args ...interface{}) ( } } -func applyFnToThis(fn, this reflect.Value, args ...interface{}) (reflect.Value, error) { +func applyFnToThis(ctx context.Context, fn, this reflect.Value, args ...interface{}) (reflect.Value, error) { + num := fn.Type().NumIn() + if num > 0 && fn.Type().In(0).Implements(hreflect.ContextInterface) { + args = append([]interface{}{ctx}, args...) + } + n := make([]reflect.Value, len(args)) for i, arg := range args { if arg == "." { @@ -75,8 +80,6 @@ func applyFnToThis(fn, this reflect.Value, args ...interface{}) (reflect.Value, } } - num := fn.Type().NumIn() - if fn.Type().IsVariadic() { num-- } diff --git a/tpl/collections/apply_test.go b/tpl/collections/apply_test.go index 1afb66808..9ad0f405d 100644 --- a/tpl/collections/apply_test.go +++ b/tpl/collections/apply_test.go @@ -73,21 +73,23 @@ func TestApply(t *testing.T) { strings := []interface{}{"a\n", "b\n"} - result, err := ns.Apply(strings, "print", "a", "b", "c") + ctx := context.Background() + + result, err := ns.Apply(ctx, strings, "print", "a", "b", "c") c.Assert(err, qt.IsNil) c.Assert(result, qt.DeepEquals, []interface{}{"abc", "abc"}) - _, err = ns.Apply(strings, "apply", ".") + _, err = ns.Apply(ctx, strings, "apply", ".") c.Assert(err, qt.Not(qt.IsNil)) var nilErr *error - _, err = ns.Apply(nilErr, "chomp", ".") + _, err = ns.Apply(ctx, nilErr, "chomp", ".") c.Assert(err, qt.Not(qt.IsNil)) - _, err = ns.Apply(strings, "dobedobedo", ".") + _, err = ns.Apply(ctx, strings, "dobedobedo", ".") c.Assert(err, qt.Not(qt.IsNil)) - _, err = ns.Apply(strings, "foo.Chomp", "c\n") + _, err = ns.Apply(ctx, strings, "foo.Chomp", "c\n") if err == nil { t.Errorf("apply with unknown func should fail") } diff --git a/tpl/collections/integration_test.go b/tpl/collections/integration_test.go new file mode 100644 index 000000000..d767c384c --- /dev/null +++ b/tpl/collections/integration_test.go @@ -0,0 +1,45 @@ +// Copyright 2022 The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package collections_test + +import ( + "testing" + + "github.com/gohugoio/hugo/hugolib" +) + +// Issue 9585 +func TestApplyWithContext(t *testing.T) { + t.Parallel() + + files := ` +-- config.toml -- +baseURL = 'http://example.com/' +-- layouts/index.html -- +{{ apply (seq 3) "partial" "foo.html"}} +-- layouts/partials/foo.html -- +{{ return "foo"}} + ` + + b := hugolib.NewIntegrationTestBuilder( + hugolib.IntegrationTestConfig{ + T: t, + TxtarString: files, + }, + ).Build() + + b.AssertFileContent("public/index.html", ` + [foo foo foo] +`) +} |