templates.go - hugo - [fork] hugo port for 9front
(HTM) git clone https://git.drkhsh.at/hugo.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
templates.go (3050B)
---
1 // Copyright 2018 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 // Package templates provides template functions for working with templates.
15 package templates
16
17 import (
18 "context"
19 "fmt"
20 "strconv"
21 "sync/atomic"
22
23 "github.com/gohugoio/hugo/common/hashing"
24 "github.com/gohugoio/hugo/deps"
25 "github.com/gohugoio/hugo/tpl"
26 "github.com/mitchellh/mapstructure"
27 )
28
29 // New returns a new instance of the templates-namespaced template functions.
30 func New(deps *deps.Deps) *Namespace {
31 ns := &Namespace{
32 deps: deps,
33 }
34
35 return ns
36 }
37
38 // Namespace provides template functions for the "templates" namespace.
39 type Namespace struct {
40 deps *deps.Deps
41 }
42
43 // Exists returns whether the template with the given name exists.
44 // Note that this is the Unix-styled relative path including filename suffix,
45 // e.g. partials/header.html
46 func (ns *Namespace) Exists(name string) bool {
47 return ns.deps.GetTemplateStore().HasTemplate(name)
48 }
49
50 // Defer defers the execution of a template block.
51 func (ns *Namespace) Defer(args ...any) (bool, error) {
52 // Prevent defer from being used in content adapters,
53 // that just doesn't work.
54 ns.deps.Site.CheckReady()
55
56 if len(args) != 0 {
57 return false, fmt.Errorf("Defer does not take any arguments")
58 }
59 return true, nil
60 }
61
62 var defferedIDCounter atomic.Uint64
63
64 type DeferOpts struct {
65 // Optional cache key. If set, the deferred block will be executed
66 // once per unique key.
67 Key string
68
69 // Optional data context to use when executing the deferred block.
70 Data any
71 }
72
73 // DoDefer defers the execution of a template block.
74 // For internal use only.
75 func (ns *Namespace) DoDefer(ctx context.Context, id string, optsv any) string {
76 var opts DeferOpts
77 if optsv != nil {
78 if err := mapstructure.WeakDecode(optsv, &opts); err != nil {
79 panic(err)
80 }
81 }
82
83 templateName := id
84 var key string
85 if opts.Key != "" {
86 key = hashing.MD5FromStringHexEncoded(opts.Key)
87 } else {
88 key = strconv.FormatUint(defferedIDCounter.Add(1), 10)
89 }
90
91 id = fmt.Sprintf("%s_%s%s", id, key, tpl.HugoDeferredTemplateSuffix)
92
93 _, _ = ns.deps.BuildState.DeferredExecutions.Executions.GetOrCreate(id,
94 func() (*tpl.DeferredExecution, error) {
95 return &tpl.DeferredExecution{
96 TemplatePath: templateName,
97 Ctx: ctx,
98 Data: opts.Data,
99 Executed: false,
100 }, nil
101 })
102
103 return id
104 }
105
106 // Get information about the currently executing template.
107 func (ns *Namespace) Current(ctx context.Context) *tpl.CurrentTemplateInfo {
108 return tpl.Context.CurrentTemplate.Get(ctx)
109 }