Add a page template func

Fixes #9339
This commit is contained in:
Bjørn Erik Pedersen
2023-02-25 09:24:59 +01:00
parent 2662faf61f
commit ce524d0b5e
54 changed files with 436 additions and 108 deletions

View File

@@ -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,

View File

@@ -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)
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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

View File

@@ -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,

View File

@@ -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,

View File

@@ -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

View File

@@ -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,

View File

@@ -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,

View File

@@ -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.

View File

@@ -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,

View File

@@ -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,

View File

@@ -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

View File

@@ -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] {

View File

@@ -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

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

View File

@@ -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,

49
tpl/page/init.go Normal file
View File

@@ -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"
)
const name = "page"
func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func(ctx context.Context, args ...interface{}) (interface{}, error) {
v := tpl.GetPageFromContext(ctx)
if v == nil {
// The multilingual sitemap does not have a page as its context.
return nil, nil
}
return v.(page.Page), nil
},
}
return ns
}
internal.AddTemplateFuncsNamespace(f)
}

View File

@@ -0,0 +1,179 @@
// Copyright 2023 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_test
import (
"fmt"
"strings"
"testing"
"github.com/gohugoio/hugo/hugolib"
)
func TestThatPageIsAvailableEverywhere(t *testing.T) {
t.Parallel()
filesTemplate := `
-- config.toml --
baseURL = 'http://example.com/'
disableKinds = ["taxonomy", "term"]
enableInlineShortcodes = true
paginate = 1
enableRobotsTXT = true
LANG_CONFIG
-- content/_index.md --
---
title: "Home"
aliases: ["/homealias/"]
---
{{< shortcode "Angled Brackets" >}}
{{% shortcode "Percentage" %}}
{{< outer >}}
{{< inner >}}
{{< /outer >}}
{{< foo.inline >}}{{ if page.IsHome }}Shortcode Inline OK.{{ end }}{{< /foo.inline >}}
## Heading
[I'm an inline-style link](https://www.google.com)
![alt text](https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png "Logo Title Text 1")
$$$bash
echo "hello";
$$$
-- content/p1.md --
-- content/p2/index.md --
-- content/p2/p2_1.md --
---
title: "P2_1"
---
{{< foo.inline >}}{{ if page.IsHome }}Shortcode in bundled page OK.{{ else}}Failed.{{ end }}{{< /foo.inline >}}
-- content/p3.md --
-- layouts/_default/_markup/render-heading.html --
{{ if page.IsHome }}
Heading OK.
{{ end }}
-- layouts/_default/_markup/render-image.html --
{{ if page.IsHome }}
Image OK.
{{ end }}
-- layouts/_default/_markup/render-link.html --
{{ if page.IsHome }}
Link OK.
{{ end }}
-- layouts/_default/myview.html
{{ if page.IsHome }}
Render OK.
{{ end }}
-- layouts/_default/_markup/render-codeblock.html --
{{ if page.IsHome }}
Codeblock OK.
{{ end }}
-- layouts/_default/single.html --
Single.
-- layouts/index.html --
{{ if eq page . }}Page OK.{{ end }}
{{ $r := "{{ if page.IsHome }}ExecuteAsTemplate OK.{{ end }}" | resources.FromString "foo.html" | resources.ExecuteAsTemplate "foo.html" . }}
{{ $r.Content }}
{{ .RenderString "{{< renderstring.inline >}}{{ if page.IsHome }}RenderString OK.{{ end }}{{< /renderstring.inline >}}}}"}}
{{ .Render "myview" }}
{{ .Content }}
partial: {{ partials.Include "foo.html" . }}
{{ $pag := (.Paginate site.RegularPages) }}
PageNumber: {{ $pag.PageNumber }}/{{ $pag.TotalPages }}|
{{ $p2 := site.GetPage "p2" }}
{{ $p2_1 := index $p2.Resources 0 }}
Bundled page: {{ $p2_1.Content }}
-- layouts/alias.html --
{{ if eq page .Page }}Alias OK.{{ else }}Failed.{{ end }}
-- layouts/404.html --
{{ if eq page . }}404 Page OK.{{ else }}Failed.{{ end }}
-- layouts/partials/foo.html --
{{ if page.IsHome }}Partial OK.{{ else }}Failed.{{ end }}
-- layouts/shortcodes/outer.html --
{{ .Inner }}
-- layouts/shortcodes/inner.html --
{{ if page.IsHome }}Shortcode Inner OK.{{ else }}Failed.{{ end }}
-- layouts/shortcodes/shortcode.html --
{{ if page.IsHome }}Shortcode {{ .Get 0 }} OK.{{ else }}Failed.{{ end }}
-- layouts/sitemap.xml --
HRE?{{ if eq page . }}Sitemap OK.{{ else }}Failed.{{ end }}
-- layouts/robots.txt --
{{ if eq page . }}Robots OK.{{ else }}Failed.{{ end }}
-- layouts/sitemapindex.xml --
{{ if not page }}SitemapIndex OK.{{ else }}Failed.{{ end }}
`
for _, multilingual := range []bool{false, true} {
t.Run(fmt.Sprintf("multilingual-%t", multilingual), func(t *testing.T) {
// Fenced code blocks.
files := strings.ReplaceAll(filesTemplate, "$$$", "```")
if multilingual {
files = strings.ReplaceAll(files, "LANG_CONFIG", `
[languages]
[languages.en]
weight = 1
[languages.no]
weight = 2
`)
} else {
files = strings.ReplaceAll(files, "LANG_CONFIG", "")
}
b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{
T: t,
TxtarString: files,
},
).Build()
b.AssertFileContent("public/index.html", `
Heading OK.
Image OK.
Link OK.
Codeblock OK.
Page OK.
Partial OK.
Shortcode Angled Brackets OK.
Shortcode Percentage OK.
Shortcode Inner OK.
Shortcode Inline OK.
ExecuteAsTemplate OK.
RenderString OK.
Render OK.
Shortcode in bundled page OK.
`)
b.AssertFileContent("public/404.html", `404 Page OK.`)
b.AssertFileContent("public/robots.txt", `Robots OK.`)
b.AssertFileContent("public/homealias/index.html", `Alias OK.`)
b.AssertFileContent("public/page/1/index.html", `Alias OK.`)
b.AssertFileContent("public/page/2/index.html", `Page OK.`)
if multilingual {
b.AssertFileContent("public/sitemap.xml", `SitemapIndex OK.`)
} else {
b.AssertFileContent("public/sitemap.xml", `Sitemap OK.`)
}
})
}
}

View File

@@ -14,6 +14,8 @@
package partials
import (
"context"
"github.com/gohugoio/hugo/deps"
"github.com/gohugoio/hugo/tpl/internal"
)
@@ -26,7 +28,7 @@ func init() {
ns := &internal.TemplateFuncsNamespace{
Name: namespaceName,
Context: func(args ...any) (any, error) { return ctx, nil },
Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil },
}
ns.AddMethodMapping(ctx.Include,

View File

@@ -14,6 +14,7 @@
package path
import (
"context"
"fmt"
"path/filepath"
@@ -29,7 +30,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.Split,

View File

@@ -15,6 +15,8 @@
package reflect
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 ctx, nil },
Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil },
}
ns.AddMethodMapping(ctx.IsMap,

View File

@@ -14,6 +14,8 @@
package resources
import (
"context"
"github.com/gohugoio/hugo/deps"
"github.com/gohugoio/hugo/tpl/internal"
)
@@ -30,7 +32,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.Get,

View File

@@ -15,11 +15,10 @@
package resources
import (
"context"
"fmt"
"sync"
"github.com/gohugoio/hugo/common/herrors"
"errors"
"github.com/gohugoio/hugo/common/maps"
@@ -227,7 +226,6 @@ func (ns *Namespace) ByType(typ any) resource.Resources {
//
// See Match for a more complete explanation about the rules used.
func (ns *Namespace) Match(pattern any) resource.Resources {
defer herrors.Recover()
patternStr, err := cast.ToStringE(pattern)
if err != nil {
panic(err)
@@ -283,7 +281,7 @@ func (ns *Namespace) FromString(targetPathIn, contentIn any) (resource.Resource,
// ExecuteAsTemplate creates a Resource from a Go template, parsed and executed with
// the given data, and published to the relative target path.
func (ns *Namespace) ExecuteAsTemplate(args ...any) (resource.Resource, error) {
func (ns *Namespace) ExecuteAsTemplate(ctx context.Context, args ...any) (resource.Resource, error) {
if len(args) != 3 {
return nil, fmt.Errorf("must provide targetPath, the template data context and a Resource object")
}
@@ -298,7 +296,7 @@ func (ns *Namespace) ExecuteAsTemplate(args ...any) (resource.Resource, error) {
return nil, fmt.Errorf("type %T not supported in Resource transformations", args[2])
}
return ns.templatesClient.ExecuteAsTemplate(r, targetPath, data)
return ns.templatesClient.ExecuteAsTemplate(ctx, r, targetPath, data)
}
// Fingerprint transforms the given Resource with a MD5 hash of the content in

View File

@@ -14,6 +14,8 @@
package safe
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.CSS,

View File

@@ -15,6 +15,8 @@
package site
import (
"context"
"github.com/gohugoio/hugo/deps"
"github.com/gohugoio/hugo/tpl/internal"
@@ -27,7 +29,7 @@ func init() {
s := d.Site
ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func(args ...any) (any, error) { return s, nil },
Context: func(cctx context.Context, args ...any) (any, error) { return s, nil },
}
if s == nil {

View File

@@ -14,6 +14,8 @@
package strings
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.Chomp,

View File

@@ -59,7 +59,6 @@ type UnusedTemplatesProvider interface {
// TemplateHandler finds and executes templates.
type TemplateHandler interface {
TemplateFinder
Execute(t Template, wr io.Writer, data any) error
ExecuteWithContext(ctx context.Context, t Template, wr io.Writer, data any) error
LookupLayout(d output.LayoutDescriptor, f output.Format) (Template, bool, error)
HasTemplate(name string) bool
@@ -153,10 +152,18 @@ type TemplateFuncGetter interface {
GetFunc(name string) (reflect.Value, bool)
}
// GetDataFromContext returns the template data context (usually .Page) from ctx if set.
// NOte: This is not fully implemented yet.
func GetDataFromContext(ctx context.Context) any {
return ctx.Value(texttemplate.DataContextKey)
// GetPageFromContext returns the top level Page.
func GetPageFromContext(ctx context.Context) any {
return ctx.Value(texttemplate.PageContextKey)
}
// SetPageInContext sets the top level Page.
func SetPageInContext(ctx context.Context, p page) context.Context {
return context.WithValue(ctx, texttemplate.PageContextKey, p)
}
type page interface {
IsNode() bool
}
func GetHasLockFromContext(ctx context.Context) bool {

View File

@@ -14,6 +14,8 @@
package templates
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.Exists,

View File

@@ -14,6 +14,7 @@
package time
import (
"context"
"errors"
"github.com/gohugoio/hugo/deps"
@@ -32,7 +33,7 @@ func init() {
ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func(args ...any) (any, error) {
Context: func(cctx context.Context, args ...any) (any, error) {
// Handle overlapping "time" namespace and func.
//
// If no args are passed to `time`, assume namespace usage and

View File

@@ -232,6 +232,10 @@ func (t templateExec) Clone(d *deps.Deps) *templateExec {
}
func (t *templateExec) Execute(templ tpl.Template, wr io.Writer, data any) error {
// TOD1
if true {
//panic("not implemented")
}
return t.ExecuteWithContext(context.Background(), templ, wr, data)
}

View File

@@ -14,6 +14,8 @@
package transform
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.Emojify,

View File

@@ -14,6 +14,8 @@
package urls
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.AbsURL,