all: Refactor to nonglobal template handling

Updates #2701
This commit is contained in:
Bjørn Erik Pedersen
2017-01-10 01:36:59 +01:00
committed by GitHub
parent 4ea4359ac1
commit d6000a208c
17 changed files with 255 additions and 209 deletions

View File

@@ -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 partial(name string, contextList ...interface{}) template.HTML {
func (t *GoHTMLTemplate) Funcs(funcMap template.FuncMap) {
t.Template.Funcs(funcMap)
}
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)
}
}