bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/bosun/conf/template/template.go (about) 1 // Package template is a thin wrapper over go's text/template and html/template packages. It allows you to use either of them with a single api. Text or HTML are inferred from the template name 2 package template 3 4 import ( 5 "bytes" 6 htemplate "html/template" 7 "io" 8 "strings" 9 ttemplate "text/template" 10 11 "github.com/aymerick/douceur/inliner" 12 ) 13 14 type iface interface { 15 Execute(io.Writer, interface{}) error 16 } 17 18 var _ htemplate.Template 19 var _ ttemplate.Template 20 21 type Template struct { 22 inner iface 23 isHTML bool 24 } 25 26 type FuncMap map[string]interface{} 27 28 func New(name string) *Template { 29 t := &Template{ 30 isHTML: isHTMLTemplate(name), 31 } 32 if t.isHTML { 33 t.inner = htemplate.New(name) 34 } else { 35 t.inner = ttemplate.New(name) 36 } 37 return t 38 } 39 40 func (t *Template) Execute(w io.Writer, ctx interface{}) error { 41 if t.isHTML { 42 // inline css for html templates 43 buf := &bytes.Buffer{} 44 err := t.inner.Execute(buf, ctx) 45 if err != nil { 46 return err 47 } 48 s, err := inliner.Inline(buf.String()) 49 if err != nil { 50 return err 51 } 52 if _, err = w.Write([]byte(s)); err != nil { 53 return err 54 } 55 } else { 56 return t.inner.Execute(w, ctx) 57 } 58 return nil 59 } 60 61 func (t *Template) copy(tmpl iface) *Template { 62 return &Template{ 63 isHTML: t.isHTML, 64 inner: tmpl, 65 } 66 } 67 68 func (t *Template) t() *ttemplate.Template { 69 return t.inner.(*(ttemplate.Template)) 70 } 71 func (t *Template) h() *htemplate.Template { 72 return t.inner.(*htemplate.Template) 73 } 74 75 func Must(t *Template, err error) *Template { 76 if err != nil { 77 panic(err) 78 } 79 return t 80 } 81 82 func (t *Template) New(name string) *Template { 83 if t.isHTML { 84 return t.copy(t.h().New(name)) 85 } 86 return t.copy(t.t().New(name)) 87 } 88 89 func (t *Template) Funcs(fm FuncMap) *Template { 90 if t.isHTML { 91 return t.copy(t.h().Funcs(htemplate.FuncMap(fm))) 92 } 93 return t.copy(t.t().Funcs(ttemplate.FuncMap(fm))) 94 } 95 96 func (t *Template) Parse(text string) (*Template, error) { 97 var i iface 98 var err error 99 if t.isHTML { 100 i, err = t.h().Parse(text) 101 } else { 102 i, err = t.t().Parse(text) 103 } 104 return t.copy(i), err 105 } 106 107 func isHTMLTemplate(name string) bool { 108 name = strings.ToLower(name) 109 if name == "emailbody" || name == "body" || strings.HasSuffix(name, "html") { 110 return true 111 } 112 return false 113 }