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