template.go (4106B)
1 package template 2 3 import ( 4 "fmt" 5 "html/template" 6 "io" 7 ) 8 9 // FuncMap is a convenience type that mirrors the FuncMap type in html/template 10 type FuncMap template.FuncMap 11 12 // HTML is another convenience type that mirrors the HTML type in html/template 13 // (http://golang.org/src/html/template/content.go?h=HTML#L120) 14 type HTML string 15 16 // AssetFunc is the function that go-bindata generates to look up a file 17 // by name 18 type AssetFunc func(string) ([]byte, error) 19 20 // Must is a helper that wraps a call to a function returning 21 // (*Template, error) and panics if the error is non-nil. It is intended for 22 // use in variable initializations such as 23 // var t = template.Must(template.New("name").Parse("templates/my.Tmpl")) 24 func Must(t *Template, err error) *Template { 25 if err != nil { 26 panic(fmt.Sprintf("template error: %s", err)) 27 } 28 if t == nil { 29 panic(fmt.Sprintf("template was nil")) 30 } 31 return t 32 } 33 34 // Template is a wrapper around a Template (from html/template). It reads 35 // template file contents from a function instead of the filesystem. 36 type Template struct { 37 AssetFunc AssetFunc 38 Tmpl *template.Template 39 } 40 41 // New creates a new Template with the given name. It stores 42 // the given Asset() function for use later. 43 // Example usage: 44 // Tmpl := template.New("mytmpl", Asset) //Asset is the function that go-bindata generated for you 45 // 46 func New(name string, fn AssetFunc) *Template { 47 return &Template{fn, template.New(name)} 48 } 49 50 // Name gets the name that was passed in the New function 51 func (t *Template) Name() string { 52 return t.Tmpl.Name() 53 } 54 55 // Funcs is a proxy to the underlying template's Funcs function 56 func (t *Template) Funcs(funcMap FuncMap) *Template { 57 return t.replaceTmpl(t.Tmpl.Funcs(template.FuncMap(funcMap))) 58 } 59 60 //Delims is a proxy to the underlying template's Delims function 61 func (t *Template) Delims(left, right string) *Template { 62 return t.replaceTmpl(t.Tmpl.Delims(left, right)) 63 } 64 65 // Parse looks up the filename in the underlying Asset store, 66 // then calls the underlying template's Parse function with the result. 67 // returns an error if the file wasn't found or the Parse call failed 68 func (t *Template) Parse(filename string) (*Template, error) { 69 tmplBytes, err := t.file(filename) 70 if err != nil { 71 return nil, err 72 } 73 newTmpl, err := t.Tmpl.Parse(string(tmplBytes)) 74 if err != nil { 75 return nil, err 76 } 77 return t.replaceTmpl(newTmpl), nil 78 } 79 80 // ParseBytes ... 81 func (t *Template) ParseBytes(by []byte) (*Template, error) { 82 newTmpl, err := t.Tmpl.Parse(string(by)) 83 if err != nil { 84 return nil, err 85 } 86 return t.replaceTmpl(newTmpl), nil 87 } 88 89 // ParseFiles looks up all of the filenames in the underlying Asset store, 90 // concatenates the file contents together, then calls the underlying template's 91 // Parse function with the result. returns an error if any of the files 92 // don't exist or the underlying Parse call failed. 93 func (t *Template) ParseFiles(filenames ...string) (*Template, error) { 94 fileBytes := []byte{} 95 for _, filename := range filenames { 96 tmplBytes, err := t.file(filename) 97 if err != nil { 98 return nil, err 99 } 100 fileBytes = append(fileBytes, tmplBytes...) 101 } 102 newTmpl, err := t.Tmpl.Parse(string(fileBytes)) 103 if err != nil { 104 return nil, err 105 } 106 return t.replaceTmpl(newTmpl), nil 107 } 108 109 // Execute is a proxy to the underlying template's Execute function 110 func (t *Template) Execute(w io.Writer, data any) error { 111 return t.Tmpl.Execute(w, data) 112 } 113 114 // ExecuteTemplate is a proxy to the underlying template's ExecuteTemplate function 115 func (t *Template) ExecuteTemplate(wr io.Writer, name string, data any) error { 116 return t.Tmpl.ExecuteTemplate(wr, name, data) 117 } 118 119 // replaceTmpl is a convenience function to replace t.Tmpl with the given Tmpl 120 func (t *Template) replaceTmpl(tmpl *template.Template) *Template { 121 t.Tmpl = tmpl 122 return t 123 } 124 125 // file is a convenience function to look up fileName using t.AssetFunc, then 126 // return the contents or an error if the file doesn't exist 127 func (t *Template) file(fileName string) ([]byte, error) { 128 tmplBytes, err := t.AssetFunc(fileName) 129 if err != nil { 130 return nil, err 131 } 132 return tmplBytes, nil 133 }