Seperate the template creating functions for as-lib use (#3225)

* Separate the template creating functions for as-lib use

Fixes #3217

Signed-off-by: Furkan <furkan.turkal@trendyol.com>
---------

Signed-off-by: Furkan <furkan.turkal@trendyol.com>
This commit is contained in:
Furkan Türkal 2023-02-24 13:24:00 +03:00 committed by GitHub
parent f1e7e4fe47
commit 57cad0d272
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 54 additions and 26 deletions

View File

@ -45,10 +45,10 @@ type Template struct {
// Option is generic modifier of the text and html templates used by a Template.
type Option func(text *tmpltext.Template, html *tmplhtml.Template)
// FromGlobs calls ParseGlob on all path globs provided and returns the
// resulting Template. Options allows customization of the text and html templates in given order.
// The DefaultFuncs have precedence over any added custom functions.
func FromGlobs(paths []string, options ...Option) (*Template, error) {
// New returns a new Template with the DefaultFuncs added. The DefaultFuncs
// have precedence over any added custom functions. Options allow customization
// of the text and html templates in given order.
func New(options ...Option) (*Template, error) {
t := &Template{
text: tmpltext.New("").Option("missingkey=zero"),
html: tmplhtml.New("").Option("missingkey=zero"),
@ -61,6 +61,17 @@ func FromGlobs(paths []string, options ...Option) (*Template, error) {
t.text.Funcs(tmpltext.FuncMap(DefaultFuncs))
t.html.Funcs(tmplhtml.FuncMap(DefaultFuncs))
return t, nil
}
// FromGlobs calls ParseGlob on all path globs provided and returns the
// resulting Template.
func FromGlobs(paths []string, options ...Option) (*Template, error) {
t, err := New(options...)
if err != nil {
return nil, err
}
defaultTemplates := []string{"default.tmpl", "email.tmpl"}
for _, file := range defaultTemplates {
@ -68,39 +79,56 @@ func FromGlobs(paths []string, options ...Option) (*Template, error) {
if err != nil {
return nil, err
}
defer f.Close()
b, err := io.ReadAll(f)
if err != nil {
if err := t.Parse(f); err != nil {
f.Close()
return nil, err
}
if t.text, err = t.text.Parse(string(b)); err != nil {
return nil, err
}
if t.html, err = t.html.Parse(string(b)); err != nil {
return nil, err
}
f.Close()
}
for _, tp := range paths {
// ParseGlob in the template packages errors if not at least one file is
// matched. We want to allow empty matches that may be populated later on.
p, err := filepath.Glob(tp)
if err != nil {
if err := t.FromGlob(tp); err != nil {
return nil, err
}
if len(p) > 0 {
if t.text, err = t.text.ParseGlob(tp); err != nil {
return nil, err
}
if t.html, err = t.html.ParseGlob(tp); err != nil {
return nil, err
}
}
}
return t, nil
}
// Parse parses the given text into the template.
func (t *Template) Parse(r io.Reader) error {
b, err := io.ReadAll(r)
if err != nil {
return err
}
if t.text, err = t.text.Parse(string(b)); err != nil {
return err
}
if t.html, err = t.html.Parse(string(b)); err != nil {
return err
}
return nil
}
// FromGlob calls ParseGlob on given path glob provided and parses into the
// template.
func (t *Template) FromGlob(path string) error {
// ParseGlob in the template packages errors if not at least one file is
// matched. We want to allow empty matches that may be populated later on.
p, err := filepath.Glob(path)
if err != nil {
return err
}
if len(p) > 0 {
if t.text, err = t.text.ParseGlob(path); err != nil {
return err
}
if t.html, err = t.html.ParseGlob(path); err != nil {
return err
}
}
return nil
}
// ExecuteTextString needs a meaningful doc comment (TODO(fabxc)).
func (t *Template) ExecuteTextString(text string, data interface{}) (string, error) {
if text == "" {