github.com/gohugoio/hugo@v0.88.1/tpl/template.go (about) 1 // Copyright 2019 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 "reflect" 19 "regexp" 20 21 "github.com/gohugoio/hugo/output" 22 23 texttemplate "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate" 24 ) 25 26 // TemplateManager manages the collection of templates. 27 type TemplateManager interface { 28 TemplateHandler 29 TemplateFuncGetter 30 AddTemplate(name, tpl string) error 31 MarkReady() error 32 } 33 34 // TemplateVariants describes the possible variants of a template. 35 // All of these may be empty. 36 type TemplateVariants struct { 37 Language string 38 OutputFormat output.Format 39 } 40 41 // TemplateFinder finds templates. 42 type TemplateFinder interface { 43 TemplateLookup 44 TemplateLookupVariant 45 } 46 47 // TemplateHandler finds and executes templates. 48 type TemplateHandler interface { 49 TemplateFinder 50 Execute(t Template, wr io.Writer, data interface{}) error 51 LookupLayout(d output.LayoutDescriptor, f output.Format) (Template, bool, error) 52 HasTemplate(name string) bool 53 } 54 55 type TemplateLookup interface { 56 Lookup(name string) (Template, bool) 57 } 58 59 type TemplateLookupVariant interface { 60 // TODO(bep) this currently only works for shortcodes. 61 // We may unify and expand this variant pattern to the 62 // other templates, but we need this now for the shortcodes to 63 // quickly determine if a shortcode has a template for a given 64 // output format. 65 // It returns the template, if it was found or not and if there are 66 // alternative representations (output format, language). 67 // We are currently only interested in output formats, so we should improve 68 // this for speed. 69 LookupVariant(name string, variants TemplateVariants) (Template, bool, bool) 70 LookupVariants(name string) []Template 71 } 72 73 // Template is the common interface between text/template and html/template. 74 type Template interface { 75 Name() string 76 Prepare() (*texttemplate.Template, error) 77 } 78 79 // TemplateParser is used to parse ad-hoc templates, e.g. in the Resource chain. 80 type TemplateParser interface { 81 Parse(name, tpl string) (Template, error) 82 } 83 84 // TemplateParseFinder provides both parsing and finding. 85 type TemplateParseFinder interface { 86 TemplateParser 87 TemplateFinder 88 } 89 90 // TemplateDebugger prints some debug info to stdout. 91 type TemplateDebugger interface { 92 Debug() 93 } 94 95 // templateInfo wraps a Template with some additional information. 96 type templateInfo struct { 97 Template 98 Info 99 } 100 101 // templateInfo wraps a Template with some additional information. 102 type templateInfoManager struct { 103 Template 104 InfoManager 105 } 106 107 // TemplatesProvider as implemented by deps.Deps. 108 type TemplatesProvider interface { 109 Tmpl() TemplateHandler 110 TextTmpl() TemplateParseFinder 111 } 112 113 // WithInfo wraps the info in a template. 114 func WithInfo(templ Template, info Info) Template { 115 if manager, ok := info.(InfoManager); ok { 116 return &templateInfoManager{ 117 Template: templ, 118 InfoManager: manager, 119 } 120 } 121 122 return &templateInfo{ 123 Template: templ, 124 Info: info, 125 } 126 } 127 128 var baseOfRe = regexp.MustCompile("template: (.*?):") 129 130 func extractBaseOf(err string) string { 131 m := baseOfRe.FindStringSubmatch(err) 132 if len(m) == 2 { 133 return m[1] 134 } 135 return "" 136 } 137 138 // TemplateFuncGetter allows to find a template func by name. 139 type TemplateFuncGetter interface { 140 GetFunc(name string) (reflect.Value, bool) 141 }