ref: c91dbe4ce9c30623ba6e686fd17efae935aa0cc5
parent: 6e0452e189884667cb58778768136ad28ac31688
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Mon Jul 13 09:40:35 EDT 2020
Fix baseof block regression From Hugo 0.74.0. Fixes #7478
--- a/hugolib/hugo_sites_build_errors_test.go
+++ b/hugolib/hugo_sites_build_errors_test.go
@@ -65,7 +65,8 @@
fileFixer: func(content string) string {return strings.Replace(content, ".Title }}", ".Title }", 1)
},
- assertCreateError: func(a testSiteBuildErrorAsserter, err error) {+ // Base templates gets parsed at build time.
+ assertBuildError: func(a testSiteBuildErrorAsserter, err error) {a.assertLineNumber(4, err)
},
},
@@ -90,7 +91,7 @@
a.c.Assert(fe.Position().LineNumber, qt.Equals, 5)
a.c.Assert(fe.Position().ColumnNumber, qt.Equals, 1)
a.c.Assert(fe.ChromaLexer, qt.Equals, "go-html-template")
- a.assertErrorMessage("\"layouts/_default/single.html:5:1\": parse failed: template: _default/single.html.___b:5: unexpected \"}\" in operand", fe.Error())+ a.assertErrorMessage("\"layouts/foo/single.html:5:1\": parse failed: template: foo/single.html:5: unexpected \"}\" in operand", fe.Error())},
},
--- a/hugolib/template_test.go
+++ b/hugolib/template_test.go
@@ -677,3 +677,46 @@
)
}
+
+// https://github.com/gohugoio/hugo/issues/7478
+func TestBaseWithAndWithoutDefine(t *testing.T) {+
+ b := newTestSitesBuilder(t)
+
+ b.WithContent("p1.md", "---\ntitle: P\n---\nContent")+
+ b.WithTemplates(
+ "_default/baseof.html", `
+::Header Start:{{ block "header" . }}{{ end }}:Header End:+::{{ block "main" . }}Main{{ end }}::+`, "index.html", `
+{{ define "header" }}+Home Header
+{{ end }}+{{ define "main" }}+This is home main
+{{ end }}+`,
+
+ "_default/single.html", `
+{{ define "main" }}+This is single main
+{{ end }}+`,
+ )
+
+ b.CreateSites().Build(BuildCfg{})+
+ b.AssertFileContent("public/index.html", `+Home Header
+This is home main
+`,
+ )
+
+ b.AssertFileContent("public/p1/index.html", `+ ::Header Start::Header End:
+This is single main
+`,
+ )
+
+}
--- a/tpl/tplimpl/template.go
+++ b/tpl/tplimpl/template.go
@@ -138,7 +138,7 @@
baseof: make(map[string]templateInfo),
needsBaseof: make(map[string]templateInfo),
- main: newTemplateNamespace(funcMap, false),
+ main: newTemplateNamespace(funcMap),
Deps: d,
layoutHandler: output.NewLayoutHandler(),
@@ -174,17 +174,11 @@
return e, nil
}
-func newTemplateNamespace(funcs map[string]interface{}, lock bool) *templateNamespace {- var mu *sync.RWMutex
- if lock {- mu = &sync.RWMutex{}- }
-
+func newTemplateNamespace(funcs map[string]interface{}) *templateNamespace { return &templateNamespace{ prototypeHTML: htmltemplate.New("").Funcs(funcs), prototypeText: texttemplate.New("").Funcs(funcs), templateStateMap: &templateStateMap{- mu: mu,
templates: make(map[string]*templateState),
},
}
@@ -426,6 +420,10 @@
t.applyTemplateTransformers(t.main, ts)
+ if err := t.extractPartials(ts.Template); err != nil {+ return nil, false, err
+ }
+
return ts, true, nil
}
@@ -570,12 +568,6 @@
if isBaseTemplatePath(name) {// Store it for later.
t.baseof[name] = tinfo
- // Also parse and add it on its own to make sure we reach the inline partials.
- tinfo.name = name + ".___b"
- _, err := t.addTemplateTo(tinfo, t.main)
- if err != nil {- return tinfo.errWithFileContext("parse failed", err)- }
return nil
}
@@ -582,12 +574,6 @@
needsBaseof := !t.noBaseNeeded(name) && needsBaseTemplate(tinfo.template)
if needsBaseof {t.needsBaseof[name] = tinfo
- // Also parse and add it on its own to make sure we reach the inline partials.
- tinfo.name = name + ".___b"
- _, err := t.addTemplateTo(tinfo, t.main)
- if err != nil {- return tinfo.errWithFileContext("parse failed", err)- }
return nil
}
@@ -748,6 +734,38 @@
return strings.Contains(name, "_markup/")
}
+func (t *templateHandler) extractPartials(templ tpl.Template) error {+ templs := templates(templ)
+ for _, templ := range templs {+ if templ.Name() == "" || !strings.HasPrefix(templ.Name(), "partials/") {+ continue
+ }
+
+ ts := newTemplateState(templ, templateInfo{name: templ.Name()})+ ts.typ = templatePartial
+
+ t.main.mu.RLock()
+ _, found := t.main.templates[templ.Name()]
+ t.main.mu.RUnlock()
+
+ if !found {+ t.main.mu.Lock()
+ // This is a template defined inline.
+ _, err := applyTemplateTransformers(ts, t.main.newTemplateLookup(ts))
+ if err != nil {+ t.main.mu.Unlock()
+ return err
+ }
+ t.main.templates[templ.Name()] = ts
+ t.main.mu.Unlock()
+
+ }
+ }
+
+ return nil
+
+}
+
func (t *templateHandler) postTransform() error {defineCheckedHTML := false
defineCheckedText := false
@@ -774,25 +792,8 @@
defineCheckedHTML = true
}
- templs := templates(v.Template)
- for _, templ := range templs {- if templ.Name() == "" || !strings.HasPrefix(templ.Name(), "partials/") {- continue
- }
-
- ts := newTemplateState(templ, templateInfo{name: templ.Name()})- ts.typ = templatePartial
-
- if _, found := t.main.templates[templ.Name()]; !found {- // This is a template defined inline.
-
- _, err := applyTemplateTransformers(ts, t.main.newTemplateLookup(ts))
- if err != nil {- return err
- }
- t.main.templates[templ.Name()] = ts
-
- }
+ if err := t.extractPartials(v.Template); err != nil {+ return err
}
}
@@ -828,20 +829,12 @@
*templateStateMap
}
-func (t templateNamespace) Clone(lock bool) *templateNamespace {- if t.mu != nil {- t.mu.Lock()
- defer t.mu.Unlock()
- }
+func (t templateNamespace) Clone() *templateNamespace {+ t.mu.Lock()
+ defer t.mu.Unlock()
- var mu *sync.RWMutex
- if lock {- mu = &sync.RWMutex{}- }
-
t.templateStateMap = &templateStateMap{templates: make(map[string]*templateState),
- mu: mu,
}
t.prototypeText = texttemplate.Must(t.prototypeText.Clone())
@@ -851,10 +844,8 @@
}
func (t *templateNamespace) Lookup(name string) (tpl.Template, bool) {- if t.mu != nil {- t.mu.RLock()
- defer t.mu.RUnlock()
- }
+ t.mu.RLock()
+ defer t.mu.RUnlock()
templ, found := t.templates[name]
if !found {@@ -861,10 +852,6 @@
return nil, false
}
- if t.mu != nil {- return &templateWrapperWithLock{RWMutex: t.mu, Template: templ}, true- }
-
return templ, found
}
@@ -892,10 +879,8 @@
}
func (t *templateNamespace) parse(info templateInfo) (*templateState, error) {- if t.mu != nil {- t.mu.Lock()
- defer t.mu.Unlock()
- }
+ t.mu.Lock()
+ defer t.mu.Unlock()
if info.isText {prototype := t.prototypeText
@@ -952,7 +937,7 @@
}
type templateStateMap struct {- mu *sync.RWMutex // May be nil
+ mu sync.RWMutex
templates map[string]*templateState
}
--
⑨