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  }