diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2023-02-25 09:24:59 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2023-02-25 19:53:18 +0100 |
commit | ce524d0b5ebaef05d29fa368465f31358f26dcda (patch) | |
tree | e5df54a5deeefacbff4916d3619f85c2cb341b01 /tpl | |
parent | 2662faf61ff0240be1ee0d6c496b6b4a6ed55fb4 (diff) |
Add a page template func
Fixes #9339
Diffstat (limited to 'tpl')
37 files changed, 350 insertions, 78 deletions
diff --git a/tpl/cast/init.go b/tpl/cast/init.go index f1badf993..84211a00b 100644 --- a/tpl/cast/init.go +++ b/tpl/cast/init.go @@ -14,6 +14,8 @@ package cast import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.ToInt, diff --git a/tpl/collections/apply.go b/tpl/collections/apply.go index 74ecc5b19..1dc09c8e5 100644 --- a/tpl/collections/apply.go +++ b/tpl/collections/apply.go @@ -40,7 +40,7 @@ func (ns *Namespace) Apply(ctx context.Context, c any, fname string, args ...any return nil, errors.New("can't iterate over a nil value") } - fnv, found := ns.lookupFunc(fname) + fnv, found := ns.lookupFunc(ctx, fname) if !found { return nil, errors.New("can't find function " + fname) } @@ -106,7 +106,7 @@ func applyFnToThis(ctx context.Context, fn, this reflect.Value, args ...any) (re return reflect.ValueOf(nil), res[1].Interface().(error) } -func (ns *Namespace) lookupFunc(fname string) (reflect.Value, bool) { +func (ns *Namespace) lookupFunc(ctx context.Context, fname string) (reflect.Value, bool) { namespace, methodName, ok := strings.Cut(fname, ".") if !ok { templ := ns.deps.Tmpl().(tpl.TemplateFuncGetter) @@ -114,16 +114,16 @@ func (ns *Namespace) lookupFunc(fname string) (reflect.Value, bool) { } // Namespace - nv, found := ns.lookupFunc(namespace) + nv, found := ns.lookupFunc(ctx, namespace) if !found { return reflect.Value{}, false } - fn, ok := nv.Interface().(func(...any) (any, error)) + fn, ok := nv.Interface().(func(context.Context, ...any) (any, error)) if !ok { return reflect.Value{}, false } - v, err := fn() + v, err := fn(ctx) if err != nil { panic(err) } diff --git a/tpl/collections/init.go b/tpl/collections/init.go index c992d3fb2..8801422ac 100644 --- a/tpl/collections/init.go +++ b/tpl/collections/init.go @@ -14,6 +14,8 @@ package collections import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.After, diff --git a/tpl/compare/init.go b/tpl/compare/init.go index 98c07f41b..f080647b1 100644 --- a/tpl/compare/init.go +++ b/tpl/compare/init.go @@ -14,6 +14,8 @@ package compare import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/langs" "github.com/gohugoio/hugo/tpl/internal" @@ -31,7 +33,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Default, diff --git a/tpl/crypto/init.go b/tpl/crypto/init.go index dddc5585a..418fbd9fb 100644 --- a/tpl/crypto/init.go +++ b/tpl/crypto/init.go @@ -14,6 +14,8 @@ package crypto import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.MD5, diff --git a/tpl/css/css.go b/tpl/css/css.go index e1783334e..5fc613011 100644 --- a/tpl/css/css.go +++ b/tpl/css/css.go @@ -1,6 +1,8 @@ package css import ( + "context" + "github.com/gohugoio/hugo/common/types/css" "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" @@ -31,7 +33,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } return ns diff --git a/tpl/data/init.go b/tpl/data/init.go index 22e685fc8..507e0d43e 100644 --- a/tpl/data/init.go +++ b/tpl/data/init.go @@ -14,6 +14,8 @@ package data import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.GetCSV, diff --git a/tpl/debug/init.go b/tpl/debug/init.go index 12a99783d..796a34bfc 100644 --- a/tpl/debug/init.go +++ b/tpl/debug/init.go @@ -14,6 +14,8 @@ package debug import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Dump, diff --git a/tpl/diagrams/init.go b/tpl/diagrams/init.go index 1ed308c57..e6356ce9c 100644 --- a/tpl/diagrams/init.go +++ b/tpl/diagrams/init.go @@ -15,6 +15,8 @@ package diagrams import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -29,7 +31,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } return ns diff --git a/tpl/encoding/init.go b/tpl/encoding/init.go index 1d42b4e37..1c3322d6e 100644 --- a/tpl/encoding/init.go +++ b/tpl/encoding/init.go @@ -14,6 +14,8 @@ package encoding import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Base64Decode, diff --git a/tpl/fmt/init.go b/tpl/fmt/init.go index b0683f061..8000627e2 100644 --- a/tpl/fmt/init.go +++ b/tpl/fmt/init.go @@ -14,6 +14,8 @@ package fmt import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Print, diff --git a/tpl/hugo/init.go b/tpl/hugo/init.go index e2b4ae7af..ad589722c 100644 --- a/tpl/hugo/init.go +++ b/tpl/hugo/init.go @@ -15,6 +15,8 @@ package hugo import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -27,7 +29,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return h, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return h, nil }, } // We just add the Hugo struct as the namespace here. No method mappings. diff --git a/tpl/images/init.go b/tpl/images/init.go index d9b9af4e7..a350d5b9d 100644 --- a/tpl/images/init.go +++ b/tpl/images/init.go @@ -14,6 +14,8 @@ package images import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Config, diff --git a/tpl/inflect/init.go b/tpl/inflect/init.go index a2d28f6bf..736e9fbd6 100644 --- a/tpl/inflect/init.go +++ b/tpl/inflect/init.go @@ -14,6 +14,8 @@ package inflect import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Humanize, diff --git a/tpl/internal/go_templates/texttemplate/hugo_template.go b/tpl/internal/go_templates/texttemplate/hugo_template.go index 96f526005..23bc18e42 100644 --- a/tpl/internal/go_templates/texttemplate/hugo_template.go +++ b/tpl/internal/go_templates/texttemplate/hugo_template.go @@ -60,29 +60,29 @@ func NewExecuter(helper ExecHelper) Executer { } type ( - dataContextKeyType string + pageContextKeyType string hasLockContextKeyType string stackContextKeyType string ) const ( - // The data object passed to Execute or ExecuteWithContext gets stored with this key if not already set. - DataContextKey = dataContextKeyType("data") + // The data page passed to ExecuteWithContext gets stored with this key. + PageContextKey = pageContextKeyType("page") // Used in partialCached to signal to nested templates that a lock is already taken. HasLockContextKey = hasLockContextKeyType("hasLock") ) // Note: The context is currently not fully implemeted in Hugo. This is a work in progress. func (t *executer) ExecuteWithContext(ctx context.Context, p Preparer, wr io.Writer, data any) error { + if ctx == nil { + panic("nil context") + } + tmpl, err := p.Prepare() if err != nil { return err } - if v := ctx.Value(DataContextKey); v == nil { - ctx = context.WithValue(ctx, DataContextKey, data) - } - value, ok := data.(reflect.Value) if !ok { value = reflect.ValueOf(data) @@ -102,28 +102,6 @@ func (t *executer) ExecuteWithContext(ctx context.Context, p Preparer, wr io.Wri return tmpl.executeWithState(state, value) } -func (t *executer) Execute(p Preparer, wr io.Writer, data any) error { - tmpl, err := p.Prepare() - if err != nil { - return err - } - - value, ok := data.(reflect.Value) - if !ok { - value = reflect.ValueOf(data) - } - - state := &state{ - helper: t.helper, - prep: p, - tmpl: tmpl, - wr: wr, - vars: []variable{{"$", value}}, - } - - return tmpl.executeWithState(state, value) -} - // Prepare returns a template ready for execution. func (t *Template) Prepare() (*Template, error) { return t, nil diff --git a/tpl/internal/templatefuncsRegistry.go b/tpl/internal/templatefuncsRegistry.go index 84e0e25fa..363f6d82f 100644 --- a/tpl/internal/templatefuncsRegistry.go +++ b/tpl/internal/templatefuncsRegistry.go @@ -17,6 +17,7 @@ package internal import ( "bytes" + "context" "encoding/json" "fmt" "go/doc" @@ -49,7 +50,7 @@ type TemplateFuncsNamespace struct { Name string // This is the method receiver. - Context func(v ...any) (any, error) + Context func(ctx context.Context, v ...any) (any, error) // Additional info, aliases and examples, per method name. MethodMappings map[string]TemplateFuncMethodMapping @@ -172,7 +173,7 @@ func (namespaces TemplateFuncsNamespaces) MarshalJSON() ([]byte, error) { if i != 0 { buf.WriteString(",") } - b, err := ns.toJSON() + b, err := ns.toJSON(context.TODO()) if err != nil { return nil, err } @@ -188,7 +189,7 @@ var ignoreFuncs = map[string]bool{ "Reset": true, } -func (t *TemplateFuncsNamespace) toJSON() ([]byte, error) { +func (t *TemplateFuncsNamespace) toJSON(ctx context.Context) ([]byte, error) { var buf bytes.Buffer godoc := getGetTplPackagesGoDoc()[t.Name] @@ -197,11 +198,11 @@ func (t *TemplateFuncsNamespace) toJSON() ([]byte, error) { buf.WriteString(fmt.Sprintf(`%q: {`, t.Name)) - ctx, err := t.Context() + tctx, err := t.Context(ctx) if err != nil { return nil, err } - ctxType := reflect.TypeOf(ctx) + ctxType := reflect.TypeOf(tctx) for i := 0; i < ctxType.NumMethod(); i++ { method := ctxType.Method(i) if ignoreFuncs[method.Name] { diff --git a/tpl/js/init.go b/tpl/js/init.go index d57e0fdcb..16e6c7efa 100644 --- a/tpl/js/init.go +++ b/tpl/js/init.go @@ -14,6 +14,8 @@ package js import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } return ns diff --git a/tpl/lang/init.go b/tpl/lang/init.go index 3f7b57ffc..62c3a56a0 100644 --- a/tpl/lang/init.go +++ b/tpl/lang/init.go @@ -14,6 +14,8 @@ package lang import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/langs" "github.com/gohugoio/hugo/tpl/internal" @@ -27,7 +29,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Translate, diff --git a/tpl/math/init.go b/tpl/math/init.go index 19905fd3a..67aa95f41 100644 --- a/tpl/math/init.go +++ b/tpl/math/init.go @@ -14,6 +14,8 @@ package math import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Add, diff --git a/tpl/openapi/openapi3/init.go b/tpl/openapi/openapi3/init.go index 8597e3294..4d88e148e 100644 --- a/tpl/openapi/openapi3/init.go +++ b/tpl/openapi/openapi3/init.go @@ -14,6 +14,8 @@ package openapi3 import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Unmarshal, diff --git a/tpl/os/init.go b/tpl/os/init.go index cd9e370cd..d7afba16f 100644 --- a/tpl/os/init.go +++ b/tpl/os/init.go @@ -14,6 +14,8 @@ package os import ( + "context" + "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/tpl/internal" ) @@ -26,7 +28,7 @@ func init() { ns := &internal.TemplateFuncsNamespace{ Name: name, - Context: func(args ...any) (any, error) { return ctx, nil }, + Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil }, } ns.AddMethodMapping(ctx.Getenv, diff --git a/tpl/page/init.go b/tpl/page/init.go new file mode 100644 index 000000000..52aeaafd6 --- /dev/null +++ b/tpl/page/init.go @@ -0,0 +1,49 @@ +// 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 page provides template functions for accessing the current Page object, +// the entry level context for the current template. +package page + +import ( + "context" + + "github.com/gohugoio/hugo/deps" + "github.com/gohugoio/hugo/resources/page" + "github.com/gohugoio/hugo/tpl" + + "github.com/gohugoio/hugo/tpl/internal" +) |