shithub: hugo

Download patch

ref: 2cbdd65330a727ae172b11b4b9dc96f675e1bb19
parent: 4e77c8717b18b8b54f4e56cb305da6cf3bc26be7
author: Bjørn Erik Pedersen <[email protected]>
date: Tue Feb 21 08:55:08 EST 2017

tpl, hugolib: Fix live-reload of non-renderable content pages

Fixes #3062

--- a/hugolib/hugo_sites_build.go
+++ b/hugolib/hugo_sites_build.go
@@ -107,6 +107,13 @@
 
 	h.runMode.Watching = config.Watching
 
+	if config.whatChanged.source {
+		// This is for the non-renderable content pages (rarely used, I guess).
+		// We could maybe detect if this is really needed, but it should be
+		// pretty fast.
+		h.Tmpl.RebuildClone()
+	}
+
 	for _, s := range h.Sites {
 		s.resetBuildState()
 	}
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -1571,6 +1571,7 @@
 	s.Info.paginationPageCount = 0
 	s.draftCount = 0
 	s.futureCount = 0
+
 	s.expiredCount = 0
 
 	for _, p := range s.rawAllPages {
--- a/tpl/template.go
+++ b/tpl/template.go
@@ -13,6 +13,7 @@
 	Templates() []*template.Template
 	New(name string) *template.Template
 	GetClone() *template.Template
+	RebuildClone() *template.Template
 	LoadTemplates(absPath string)
 	LoadTemplatesWithPrefix(absPath, prefix string)
 	AddTemplate(name, tpl string) error
--- a/tpl/tplimpl/template.go
+++ b/tpl/tplimpl/template.go
@@ -44,7 +44,12 @@
 type GoHTMLTemplate struct {
 	*template.Template
 
-	clone *template.Template
+	// This looks, and is, strange.
+	// The clone is used by non-renderable content pages, and these need to be
+	// re-parsed on content change, and to avoid the
+	// "cannot Parse after Execute" error, we need to re-clone it from the original clone.
+	clone      *template.Template
+	cloneClone *template.Template
 
 	// a separate storage for the overlays created from cloned master templates.
 	// note: No mutex protection, so we add these in one Go routine, then just read.
@@ -66,7 +71,6 @@
 // Update updates the Hugo Template System in the provided Deps.
 // with all the additional features, templates & functions
 func (*TemplateProvider) Update(deps *deps.Deps) error {
-	// TODO(bep) check that this isn't called too many times.
 	tmpl := &GoHTMLTemplate{
 		Template: template.New(""),
 		overlays: make(map[string]*template.Template),
@@ -229,6 +233,11 @@
 	return t.clone
 }
 
+func (t *GoHTMLTemplate) RebuildClone() *template.Template {
+	t.clone = template.Must(t.cloneClone.Clone())
+	return t.clone
+}
+
 func (t *GoHTMLTemplate) LoadEmbedded() {
 	t.EmbedShortcodes()
 	t.EmbedTemplates()
@@ -236,9 +245,12 @@
 
 // MarkReady marks the template as "ready for execution". No changes allowed
 // after this is set.
+// TODO(bep) if this proves to be resource heavy, we could detect
+// earlier if we really need this, or make it lazy.
 func (t *GoHTMLTemplate) MarkReady() {
 	if t.clone == nil {
 		t.clone = template.Must(t.Template.Clone())
+		t.cloneClone = template.Must(t.clone.Clone())
 	}
 }