mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-28 22:19:59 +02:00
@@ -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,
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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.
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -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] {
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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
49
tpl/page/init.go
Normal 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)
|
||||
}
|
179
tpl/page/integration_test.go
Normal file
179
tpl/page/integration_test.go
Normal 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)
|
||||
|
||||

|
||||
|
||||
$$$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.`)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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 {
|
||||
|
@@ -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,
|
||||
|
@@ -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 {
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user