diff --git a/hugolib/content_render_hooks_test.go b/hugolib/content_render_hooks_test.go index 17d273a33..13bfe216a 100644 --- a/hugolib/content_render_hooks_test.go +++ b/hugolib/content_render_hooks_test.go @@ -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" diff --git a/hugolib/page.go b/hugolib/page.go index 859834b91..fac3f3492 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -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, } } diff --git a/hugolib/site.go b/hugolib/site.go index 3d77b014a..c89995ab0 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -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 } diff --git a/identity/identity.go b/identity/identity.go index 8fce16479..b002f34f0 100644 --- a/identity/identity.go +++ b/identity/identity.go @@ -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 diff --git a/markup/goldmark/convert.go b/markup/goldmark/convert.go index ffe9cd45a..2a66cc184 100644 --- a/markup/goldmark/convert.go +++ b/markup/goldmark/convert.go @@ -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) } diff --git a/markup/goldmark/render_hooks.go b/markup/goldmark/render_hooks.go index aaae68e7f..c541cbba4 100644 --- a/markup/goldmark/render_hooks.go +++ b/markup/goldmark/render_hooks.go @@ -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 }