Fix server rebuild issue with partials referenced from render hooks
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 26 Nov 2020 07:32:49 +0000 (08:32 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 26 Nov 2020 19:41:54 +0000 (20:41 +0100)
Fixes #7990

hugolib/content_render_hooks_test.go
hugolib/page.go
hugolib/site.go
identity/identity.go
markup/goldmark/convert.go
markup/goldmark/render_hooks.go

index 17d273a33fdd50e32ab5a150a2a8c59a6bcdf240..13bfe216a814f073b937577392cf46db43b8f586 100644 (file)
@@ -20,6 +20,43 @@ import (
        qt "github.com/frankban/quicktest"
 )
 
+func TestRenderHookEditNestedPartial(t *testing.T) {
+       config := `
+baseURL="https://example.org"
+workingDir="/mywork"
+`
+       b := newTestSitesBuilder(t).WithWorkingDir("/mywork").WithConfigFile("toml", config).Running()
+
+       b.WithTemplates("_default/single.html", "{{ .Content }}")
+       b.WithTemplates("partials/mypartial1.html", `PARTIAL1 {{ partial "mypartial2.html" }}`)
+       b.WithTemplates("partials/mypartial2.html", `PARTIAL2`)
+       b.WithTemplates("_default/_markup/render-link.html", `Link {{ .Text | safeHTML }}|{{ partial "mypartial1.html" . }}END`)
+
+       b.WithContent("p1.md", `---
+title: P1
+---
+
+[First Link](https://www.google.com "Google's Homepage")
+
+`)
+       b.Build(BuildCfg{})
+
+       b.AssertFileContent("public/p1/index.html", `Link First Link|PARTIAL1 PARTIAL2END`)
+
+       b.EditFiles("layouts/partials/mypartial1.html", `PARTIAL1_EDITED {{ partial "mypartial2.html" }}`)
+
+       b.Build(BuildCfg{})
+
+       b.AssertFileContent("public/p1/index.html", `Link First Link|PARTIAL1_EDITED PARTIAL2END`)
+
+       b.EditFiles("layouts/partials/mypartial2.html", `PARTIAL2_EDITED`)
+
+       b.Build(BuildCfg{})
+
+       b.AssertFileContent("public/p1/index.html", `Link First Link|PARTIAL1_EDITED PARTIAL2_EDITEDEND`)
+
+}
+
 func TestRenderHooks(t *testing.T) {
        config := `
 baseURL="https://example.org"
index 859834b91e52a47ac8873846d86232fd63e45d14..fac3f349230db6a431d3d469bff8817ea284b614 100644 (file)
@@ -409,7 +409,7 @@ func (p *pageState) createRenderHooks(f output.Format) (*hooks.Renderers, error)
        if templFound {
                renderers.LinkRenderer = hookRenderer{
                        templateHandler: p.s.Tmpl(),
-                       Provider:        templ.(tpl.Info),
+                       SearchProvider:  templ.(identity.SearchProvider),
                        templ:           templ,
                }
        }
@@ -422,7 +422,7 @@ func (p *pageState) createRenderHooks(f output.Format) (*hooks.Renderers, error)
        if templFound {
                renderers.ImageRenderer = hookRenderer{
                        templateHandler: p.s.Tmpl(),
-                       Provider:        templ.(tpl.Info),
+                       SearchProvider:  templ.(identity.SearchProvider),
                        templ:           templ,
                }
        }
@@ -435,7 +435,7 @@ func (p *pageState) createRenderHooks(f output.Format) (*hooks.Renderers, error)
        if templFound {
                renderers.HeadingRenderer = hookRenderer{
                        templateHandler: p.s.Tmpl(),
-                       Provider:        templ.(tpl.Info),
+                       SearchProvider:  templ.(identity.SearchProvider),
                        templ:           templ,
                }
        }
index 3d77b014af3fca16b0b5a4e0086fe4762f2d5cc4..c89995ab0f0d2835d41a29432557b664ba246418 100644 (file)
@@ -1738,7 +1738,7 @@ var infoOnMissingLayout = map[string]bool{
 // where ITEM is the thing being hooked.
 type hookRenderer struct {
        templateHandler tpl.TemplateHandler
-       identity.Provider
+       identity.SearchProvider
        templ tpl.Template
 }
 
index 8fce16479bbb0ea62f25ebc4e4883f2447609444..b002f34f00127ebf04f742eaed7da31dcc9224a1 100644 (file)
@@ -64,13 +64,18 @@ type Identity interface {
 
 // Manager manages identities, and is itself a Provider of Identity.
 type Manager interface {
-       IdentitiesProvider
-       Provider
+       SearchProvider
        Add(ids ...Provider)
-       Search(id Identity) Provider
        Reset()
 }
 
+// SearchProvider provides access to the chained set of identities.
+type SearchProvider interface {
+       Provider
+       IdentitiesProvider
+       Search(id Identity) Provider
+}
+
 // A PathIdentity is a common identity identified by a type and a path, e.g. "layouts" and "_default/single.html".
 type PathIdentity struct {
        Type string
index ffe9cd45a81fe2421f58d44016a2528dddbece0b..2a66cc18454a069ff35cfe556d913049e7f5fc73 100644 (file)
@@ -202,7 +202,7 @@ type renderContext struct {
 type renderContextData interface {
        RenderContext() converter.RenderContext
        DocumentContext() converter.DocumentContext
-       AddIdentity(id identity.Identity)
+       AddIdentity(id identity.Provider)
 }
 
 type renderContextDataHolder struct {
@@ -219,7 +219,7 @@ func (ctx *renderContextDataHolder) DocumentContext() converter.DocumentContext
        return ctx.dctx
 }
 
-func (ctx *renderContextDataHolder) AddIdentity(id identity.Identity) {
+func (ctx *renderContextDataHolder) AddIdentity(id identity.Provider) {
        ctx.ids.Add(id)
 }
 
index aaae68e7f9e5ab1213a394b72986cad8fcb4739c..c541cbba4c7df498241450fef6fa261e277d6a2b 100644 (file)
@@ -186,7 +186,7 @@ func (r *hookedRenderer) renderImage(w util.BufWriter, source []byte, node ast.N
                },
        )
 
-       ctx.AddIdentity(h.ImageRenderer.GetIdentity())
+       ctx.AddIdentity(h.ImageRenderer)
 
        return ast.WalkContinue, err
 
@@ -248,7 +248,10 @@ func (r *hookedRenderer) renderLink(w util.BufWriter, source []byte, node ast.No
                },
        )
 
-       ctx.AddIdentity(h.LinkRenderer.GetIdentity())
+       // TODO(bep) I have a working branch that fixes these rather confusing identity types,
+       // but for now it's important that it's not .GetIdentity() that's added here,
+       // to make sure we search the entire chain on changes.
+       ctx.AddIdentity(h.LinkRenderer)
 
        return ast.WalkContinue, err
 }
@@ -308,7 +311,7 @@ func (r *hookedRenderer) renderHeading(w util.BufWriter, source []byte, node ast
                },
        )
 
-       ctx.AddIdentity(h.HeadingRenderer.GetIdentity())
+       ctx.AddIdentity(h.HeadingRenderer)
 
        return ast.WalkContinue, err
 }