github.com/shohhei1126/hugo@v0.42.2-0.20180623210752-3d5928889ad7/tpl/template.go (about) 1 // Copyright 2017-present 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 tpl 15 16 import ( 17 "io" 18 "time" 19 20 "text/template/parse" 21 22 "html/template" 23 texttemplate "text/template" 24 25 bp "github.com/gohugoio/hugo/bufferpool" 26 "github.com/gohugoio/hugo/metrics" 27 ) 28 29 var ( 30 _ TemplateExecutor = (*TemplateAdapter)(nil) 31 ) 32 33 // TemplateHandler manages the collection of templates. 34 type TemplateHandler interface { 35 TemplateFinder 36 AddTemplate(name, tpl string) error 37 AddLateTemplate(name, tpl string) error 38 LoadTemplates(prefix string) 39 PrintErrors() 40 41 MarkReady() 42 RebuildClone() 43 } 44 45 // TemplateFinder finds templates. 46 type TemplateFinder interface { 47 Lookup(name string) *TemplateAdapter 48 } 49 50 // Template is the common interface between text/template and html/template. 51 type Template interface { 52 Execute(wr io.Writer, data interface{}) error 53 Name() string 54 } 55 56 // TemplateExecutor adds some extras to Template. 57 type TemplateExecutor interface { 58 Template 59 ExecuteToString(data interface{}) (string, error) 60 Tree() string 61 } 62 63 // TemplateDebugger prints some debug info to stdoud. 64 type TemplateDebugger interface { 65 Debug() 66 } 67 68 // TemplateAdapter implements the TemplateExecutor interface. 69 type TemplateAdapter struct { 70 Template 71 Metrics metrics.Provider 72 } 73 74 // Execute executes the current template. The actual execution is performed 75 // by the embedded text or html template, but we add an implementation here so 76 // we can add a timer for some metrics. 77 func (t *TemplateAdapter) Execute(w io.Writer, data interface{}) error { 78 if t.Metrics != nil { 79 defer t.Metrics.MeasureSince(t.Name(), time.Now()) 80 } 81 return t.Template.Execute(w, data) 82 } 83 84 // ExecuteToString executes the current template and returns the result as a 85 // string. 86 func (t *TemplateAdapter) ExecuteToString(data interface{}) (string, error) { 87 b := bp.GetBuffer() 88 defer bp.PutBuffer(b) 89 if err := t.Execute(b, data); err != nil { 90 return "", err 91 } 92 return b.String(), nil 93 } 94 95 // Tree returns the template Parse tree as a string. 96 // Note: this isn't safe for parallel execution on the same template 97 // vs Lookup and Execute. 98 func (t *TemplateAdapter) Tree() string { 99 var tree *parse.Tree 100 switch tt := t.Template.(type) { 101 case *template.Template: 102 tree = tt.Tree 103 case *texttemplate.Template: 104 tree = tt.Tree 105 default: 106 panic("Unknown template") 107 } 108 109 if tree == nil || tree.Root == nil { 110 return "" 111 } 112 s := tree.Root.String() 113 114 return s 115 } 116 117 // TemplateFuncsGetter allows to get a map of functions. 118 type TemplateFuncsGetter interface { 119 GetFuncs() map[string]interface{} 120 } 121 122 // TemplateTestMocker adds a way to override some template funcs during tests. 123 // The interface is named so it's not used in regular application code. 124 type TemplateTestMocker interface { 125 SetFuncs(funcMap map[string]interface{}) 126 }