diff options
Diffstat (limited to 'internal/template.go')
-rw-r--r-- | internal/template.go | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/internal/template.go b/internal/template.go index 4079f52..2fe9923 100644 --- a/internal/template.go +++ b/internal/template.go @@ -1,26 +1,51 @@ package internal import ( + "bytes" "strings" + "sync" gotemplate "text/template" ) // Template stores the template for a string. type Template struct { - Src string - Template *gotemplate.Template - ParseErr *error + Src string + LeftDelim string + RightDelim string + + parseOnce sync.Once + parsedTemplate *gotemplate.Template + parseError error } -func (t *Template) Parse(leftDelim, rightDelim string, funcs gotemplate.FuncMap) error { - if t.ParseErr == nil { - if strings.Contains(t.Src, leftDelim) { - gt, err := gotemplate.New("").Funcs(funcs).Delims(leftDelim, rightDelim).Parse(t.Src) - t.Template = gt - t.ParseErr = &err - } else { - t.ParseErr = new(error) - } +func (t *Template) Execute(funcs gotemplate.FuncMap, data interface{}) (string, error) { + leftDelim := t.LeftDelim + if leftDelim == "" { + leftDelim = "{{" + } + if !strings.Contains(t.Src, leftDelim) { + // Fast path to avoid parsing a template that has no actions. + return t.Src, nil + } + + var gt *gotemplate.Template + var err error + if funcs == nil { + t.parseOnce.Do(func() { + // If funcs is nil, then we only need to parse this template once. + t.parsedTemplate, t.parseError = gotemplate.New("").Delims(t.LeftDelim, t.RightDelim).Parse(t.Src) + }) + gt, err = t.parsedTemplate, t.parseError + } else { + gt, err = gotemplate.New("").Delims(t.LeftDelim, t.RightDelim).Funcs(funcs).Parse(t.Src) + } + + if err != nil { + return "", err + } + var buf bytes.Buffer + if err := gt.Execute(&buf, data); err != nil { + return "", err } - return *t.ParseErr + return buf.String(), nil } |