From d6000a208c7687ca3a3efd6961ac941ce325e199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Tue, 10 Jan 2017 01:36:59 +0100 Subject: all: Refactor to nonglobal template handling Updates #2701 --- tpl/template.go | 88 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 42 deletions(-) (limited to 'tpl/template.go') diff --git a/tpl/template.go b/tpl/template.go index db6a912ff..b26490f0c 100644 --- a/tpl/template.go +++ b/tpl/template.go @@ -30,10 +30,8 @@ import ( "github.com/yosssi/ace" ) -var localTemplates *template.Template - -// TODO(bep) globals get rid of the reset of the jww.ERR etc. -var tmpl *GoHTMLTemplate +// TODO(bep) globals get rid of the rest of the jww.ERR etc. +//var tmpl *GoHTMLTemplate // TODO(bep) an interface with hundreds of methods ... remove it. // And unexport most of these methods. @@ -45,13 +43,13 @@ type Template interface { GetClone() *template.Template LoadTemplates(absPath string) LoadTemplatesWithPrefix(absPath, prefix string) - MarkReady() AddTemplate(name, tpl string) error AddTemplateFileWithMaster(name, overlayFilename, masterFilename string) error AddAceTemplate(name, basePath, innerPath string, baseContent, innerContent []byte) error AddInternalTemplate(prefix, name, tpl string) error AddInternalShortcode(name, tpl string) error PrintErrors() + Funcs(funcMap template.FuncMap) } type templateErr struct { @@ -60,7 +58,8 @@ type templateErr struct { } type GoHTMLTemplate struct { - template.Template + *template.Template + clone *template.Template // a separate storage for the overlays created from cloned master templates. @@ -69,41 +68,54 @@ type GoHTMLTemplate struct { errors []*templateErr + funcster *templateFuncster + // TODO(bep) globals template log *jww.Notepad } -// InitializeT resets the internal template state to its initial state -func InitializeT(logger *jww.Notepad) *GoHTMLTemplate { - tmpl = New(logger) - return tmpl -} - // New returns a new Hugo Template System // with all the additional features, templates & functions -func New(logger *jww.Notepad) *GoHTMLTemplate { - var templates = &GoHTMLTemplate{ - Template: *template.New(""), +func New(logger *jww.Notepad, withTemplate ...func(templ Template) error) *GoHTMLTemplate { + tmpl := &GoHTMLTemplate{ + Template: template.New(""), overlays: make(map[string]*template.Template), errors: make([]*templateErr, 0), log: logger, } - localTemplates = &templates.Template + tmpl.funcster = newTemplateFuncster(tmpl) // The URL funcs in the funcMap is somewhat language dependent, // so we need to wait until the language and site config is loaded. - initFuncMap() + // TODO(bep) globals + tmpl.funcster.initFuncMap() - for k, v := range funcMap { + // TODO(bep) globals + for k, v := range tmpl.funcster.funcMap { amber.FuncMap[k] = v } - templates.Funcs(funcMap) - templates.LoadEmbedded() - return templates + + tmpl.LoadEmbedded() + + for _, wt := range withTemplate { + err := wt(tmpl) + if err != nil { + tmpl.errors = append(tmpl.errors, &templateErr{"init", err}) + } + + } + + tmpl.markReady() + + return tmpl +} + +func (t *GoHTMLTemplate) Funcs(funcMap template.FuncMap) { + t.Template.Funcs(funcMap) } -func partial(name string, contextList ...interface{}) template.HTML { +func (t *GoHTMLTemplate) partial(name string, contextList ...interface{}) template.HTML { if strings.HasPrefix("partials/", name) { name = name[8:] } @@ -114,16 +126,16 @@ func partial(name string, contextList ...interface{}) template.HTML { } else { context = contextList[0] } - return ExecuteTemplateToHTML(context, "partials/"+name, "theme/partials/"+name) + return t.ExecuteTemplateToHTML(context, "partials/"+name, "theme/partials/"+name) } -func executeTemplate(context interface{}, w io.Writer, layouts ...string) { +func (t *GoHTMLTemplate) executeTemplate(context interface{}, w io.Writer, layouts ...string) { var worked bool for _, layout := range layouts { - templ := Lookup(layout) + templ := t.Lookup(layout) if templ == nil { layout += ".html" - templ = Lookup(layout) + templ = t.Lookup(layout) } if templ != nil { @@ -136,28 +148,20 @@ func executeTemplate(context interface{}, w io.Writer, layouts ...string) { } } if !worked { - tmpl.log.ERROR.Println("Unable to render", layouts) - tmpl.log.ERROR.Println("Expecting to find a template in either the theme/layouts or /layouts in one of the following relative locations", layouts) + t.log.ERROR.Println("Unable to render", layouts) + t.log.ERROR.Println("Expecting to find a template in either the theme/layouts or /layouts in one of the following relative locations", layouts) } } -func ExecuteTemplateToHTML(context interface{}, layouts ...string) template.HTML { +func (t *GoHTMLTemplate) ExecuteTemplateToHTML(context interface{}, layouts ...string) template.HTML { b := bp.GetBuffer() defer bp.PutBuffer(b) - executeTemplate(context, b, layouts...) + t.executeTemplate(context, b, layouts...) return template.HTML(b.String()) } -func Lookup(name string) *template.Template { - return tmpl.Lookup(name) -} - func (t *GoHTMLTemplate) Lookup(name string) *template.Template { - if templ := localTemplates.Lookup(name); templ != nil { - return templ - } - if t.overlays != nil { if templ, ok := t.overlays[name]; ok { return templ @@ -183,9 +187,9 @@ func (t *GoHTMLTemplate) LoadEmbedded() { t.EmbedTemplates() } -// MarkReady marks the template as "ready for execution". No changes allowed +// markReady marks the template as "ready for execution". No changes allowed // after this is set. -func (t *GoHTMLTemplate) MarkReady() { +func (t *GoHTMLTemplate) markReady() { if t.clone == nil { t.clone = template.Must(t.Template.Clone()) } @@ -522,7 +526,7 @@ func (t *GoHTMLTemplate) LoadTemplates(absPath string) { } func (t *GoHTMLTemplate) PrintErrors() { - for _, e := range t.errors { - t.log.ERROR.Println(e.err) + for i, e := range t.errors { + t.log.ERROR.Println(i, ":", e.err) } } -- cgit v1.2.3