Create template clone for late template execution

Fixing some breaking blogs on Go 1.6

Fixes #1879
This commit is contained in:
Bjørn Erik Pedersen 2016-02-28 11:51:51 +01:00
parent 804603155f
commit 93b04e67f6
2 changed files with 26 additions and 1 deletions

View file

@ -595,6 +595,7 @@ func (s *Site) prepTemplates() {
if s.hasTheme() { if s.hasTheme() {
s.Tmpl.LoadTemplatesWithPrefix(s.absThemeDir()+"/layouts", "theme") s.Tmpl.LoadTemplatesWithPrefix(s.absThemeDir()+"/layouts", "theme")
} }
s.Tmpl.MarkReady()
} }
func (s *Site) addTemplate(name, data string) error { func (s *Site) addTemplate(name, data string) error {
@ -1366,11 +1367,15 @@ func (s *Site) RenderPages() error {
// this cannot be fanned out to multiple Go routines // this cannot be fanned out to multiple Go routines
// See issue #1601 // See issue #1601
// TODO(bep): Check the IsRenderable logic. // TODO(bep): Check the IsRenderable logic.
// Issue #1879
templ := s.Tmpl.Clone()
for _, p := range s.Pages { for _, p := range s.Pages {
var layouts []string var layouts []string
if !p.IsRenderable() { if !p.IsRenderable() {
self := "__" + p.TargetPath() self := "__" + p.TargetPath()
_, err := s.Tmpl.New(self).Parse(string(p.Content)) _, err := templ.New(self).Parse(string(p.Content))
if err != nil { if err != nil {
results <- err results <- err
continue continue

View file

@ -37,12 +37,14 @@ type Template interface {
Lookup(name string) *template.Template Lookup(name string) *template.Template
Templates() []*template.Template Templates() []*template.Template
New(name string) *template.Template New(name string) *template.Template
Clone() *template.Template
LoadTemplates(absPath string) LoadTemplates(absPath string)
LoadTemplatesWithPrefix(absPath, prefix string) LoadTemplatesWithPrefix(absPath, prefix string)
AddTemplate(name, tpl string) error AddTemplate(name, tpl string) error
AddAceTemplate(name, basePath, innerPath string, baseContent, innerContent []byte) error AddAceTemplate(name, basePath, innerPath string, baseContent, innerContent []byte) error
AddInternalTemplate(prefix, name, tpl string) error AddInternalTemplate(prefix, name, tpl string) error
AddInternalShortcode(name, tpl string) error AddInternalShortcode(name, tpl string) error
MarkReady()
PrintErrors() PrintErrors()
} }
@ -53,6 +55,8 @@ type templateErr struct {
type GoHTMLTemplate struct { type GoHTMLTemplate struct {
template.Template template.Template
clone *template.Template
ready bool
errors []*templateErr errors []*templateErr
} }
@ -140,6 +144,22 @@ func (t *GoHTMLTemplate) LoadEmbedded() {
t.EmbedTemplates() t.EmbedTemplates()
} }
// MarkReady marks the template as "ready for execution". No changes allowed
// after this is set.
func (t *GoHTMLTemplate) MarkReady() {
t.clone = template.Must(t.Template.Clone())
t.ready = true
}
// Since Go 1.6, the template cannot change once executed. So we have to create
// a clone and work with that in some rare cases.
func (t *GoHTMLTemplate) Clone() *template.Template {
if !t.ready {
panic("template clone called too early")
}
return template.Must(t.clone.Clone())
}
func (t *GoHTMLTemplate) AddInternalTemplate(prefix, name, tpl string) error { func (t *GoHTMLTemplate) AddInternalTemplate(prefix, name, tpl string) error {
if prefix != "" { if prefix != "" {
return t.AddTemplate("_internal/"+prefix+"/"+name, tpl) return t.AddTemplate("_internal/"+prefix+"/"+name, tpl)