github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/htmlrender/dom/template.go (about) 1 package dom 2 3 import ( 4 "bytes" 5 "errors" 6 "html/template" 7 "sync" 8 ) 9 10 var errUnsafeWriterNotSupported = errors.New("Unsafe writing unsupported.") 11 12 type Template struct { 13 Content string 14 15 once sync.Once 16 tmpl *template.Template 17 err error 18 } 19 20 func NewTemplate(content string) (*Template, error) { 21 t := &Template{Content: content} 22 t.compile() 23 return t, t.err 24 } 25 26 func MustTemplate(content string) *Template { 27 t, err := NewTemplate(content) 28 if err != nil { 29 panic(err) 30 } 31 return t 32 } 33 34 func (t *Template) Renderer(data interface{}) Renderer { 35 return RenderFunc(func(w Writer) { 36 t.RenderData(data, w) 37 }) 38 } 39 40 func (t *Template) compile() { 41 t.once.Do(func() { 42 tmpl, err := template.New("").Funcs(template.FuncMap{ 43 "Render": RenderHTML, 44 }).Parse(t.Content) 45 46 if err != nil { 47 t.err = err 48 return 49 } 50 51 t.tmpl = tmpl 52 }) 53 } 54 55 func (t *Template) RenderData(data interface{}, w Writer) { 56 t.compile() 57 58 if t.err != nil { 59 Error{t.err}.Render(w) 60 return 61 } 62 63 uw, ok := w.(UnsafeWriter) 64 if !ok { 65 Error{errUnsafeWriterNotSupported}.Render(w) 66 return 67 } 68 69 var buf bytes.Buffer 70 err := t.tmpl.Execute(&buf, data) 71 if err != nil { 72 Error{err}.Render(w) 73 return 74 } 75 76 uw.UnsafeContent(buf.String()) 77 } 78 79 func RenderHTML(r Renderer) template.HTML { 80 w := NewWriter() 81 r.Render(w) 82 return template.HTML(w.String()) 83 } 84 85 // type TemplateFile