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 }