Skip to content

Commit

Permalink
Fix server edits of resources included in shortcode/hooks
Browse files Browse the repository at this point in the history
Fixes #13093
  • Loading branch information
bep committed Nov 28, 2024
1 parent 88b7868 commit c09ef5b
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 11 deletions.
3 changes: 3 additions & 0 deletions hugolib/page__content.go
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,9 @@ type cachedContentScope struct {
}

func (c *cachedContentScope) prepareContext(ctx context.Context) context.Context {
// Make sure we assign any render hook dependencies to the closest page.
ctx = tpl.Context.DependencyManagerScopedProvider.Set(ctx, c.pco.po.p)

// The markup scope is recursive, so if already set to a non zero value, preserve that value.
if s := hugo.GetMarkupScope(ctx); s != "" || s == c.scope {
return ctx
Expand Down
73 changes: 63 additions & 10 deletions hugolib/rebuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@ const rebuildFilesSimple = `
baseURL = "https://example.com"
disableKinds = ["term", "taxonomy", "sitemap", "robotstxt", "404"]
disableLiveReload = true
[outputFormats]
[outputFormats.rss]
weight = 10
[outputFormats.html]
weight = 20
[outputs]
home = ["html"]
home = ["rss", "html"]
section = ["html"]
page = ["html"]
-- content/mysection/_index.md --
Expand Down Expand Up @@ -58,6 +63,19 @@ Home Text Content.
title: "myothersectionpage"
---
myothersectionpage Content.
-- content/mythirdsection/mythirdsectionpage.md --
---
title: "mythirdsectionpage"
---
mythirdsectionpage Content.
{{< mytext >}}
§§§ myothertext
foo
§§§
-- assets/mytext.txt --
Assets My Text.
-- assets/myothertext.txt --
Assets My Other Text.
-- layouts/_default/single.html --
Single: {{ .Title }}|{{ .Content }}$
Resources: {{ range $i, $e := .Resources }}{{ $i }}:{{ .RelPermalink }}|{{ .Content }}|{{ end }}$
Expand All @@ -68,6 +86,12 @@ Len Resources: {{ len .Resources }}|
Resources: {{ range $i, $e := .Resources }}{{ $i }}:{{ .RelPermalink }}|{{ .Content }}|{{ end }}$
-- layouts/shortcodes/foo.html --
Foo.
-- layouts/shortcodes/mytext.html --
{{ $r := resources.Get "mytext.txt" }}
My Text: {{ $r.Content }}|{{ $r.Permalink }}|
-- layouts/_default/_markup/render-codeblock-myothertext.html --
{{ $r := resources.Get "myothertext.txt" }}
My Other Text: {{ $r.Content }}|{{ $r.Permalink }}|
`

Expand All @@ -83,6 +107,35 @@ func TestRebuildEditTextFileInLeafBundle(t *testing.T) {
b.AssertRenderCountContent(1)
}

func TestRebuildEditTextFileInShortcode(t *testing.T) {
b := TestRunning(t, rebuildFilesSimple)
b.AssertFileContent("public/mythirdsection/mythirdsectionpage/index.html",
"Text: Assets My Text.")
b.AssertFileContent("public/mytext.txt", "Assets My Text.")
b.EditFileReplaceAll("assets/mytext.txt", "My Text", "My Text Edited").Build()
time.Sleep(100 * time.Millisecond)
b.AssertFileContent("public/mytext.txt", "Assets My Text Edited.")
b.AssertFileContent("public/mythirdsection/mythirdsectionpage/index.html",
"Text: Assets My Text Edited.")
b.AssertRenderCountPage(2)
b.AssertRenderCountContent(1)
}

func TestRebuildEditTextFileInHook(t *testing.T) {
b := TestRunning(t, rebuildFilesSimple)
b.AssertFileContent("public/mythirdsection/mythirdsectionpage/index.html",
"Text: Assets My Other Text.")
b.AssertFileContent("public/myothertext.txt", "Assets My Other Text.")
b.EditFileReplaceAll("assets/myothertext.txt", "My Other Text", "My Other Text Edited").Build()
b.AssertFileContent("assets/myothertext.txt", "Assets My Other Text Edited.")
time.Sleep(100 * time.Millisecond)
b.AssertFileContent("public/myothertext.txt", "Assets My Other Text Edited.")
b.AssertFileContent("public/mythirdsection/mythirdsectionpage/index.html",
"Text: Assets My Other Text Edited.")
b.AssertRenderCountPage(2)
b.AssertRenderCountContent(1)
}

func TestRebuiEditUnmarshaledYamlFileInLeafBundle(t *testing.T) {
files := `
-- hugo.toml --
Expand Down Expand Up @@ -140,8 +193,8 @@ func TestRebuildRenameTextFileInLeafBundle(t *testing.T) {

b.RenameFile("content/mysection/mysectionbundle/mysectionbundletext.txt", "content/mysection/mysectionbundle/mysectionbundletext2.txt").Build()
b.AssertFileContent("public/mysection/mysectionbundle/index.html", "mysectionbundletext2", "My Section Bundle Text 2 Content.", "Len Resources: 2|")
b.AssertRenderCountPage(5)
b.AssertRenderCountContent(6)
b.AssertRenderCountPage(8)
b.AssertRenderCountContent(8)
})
}

Expand All @@ -161,8 +214,8 @@ func TestRebuilEditContentFileThenAnother(t *testing.T) {

b.EditFileReplaceAll("content/myothersection/myothersectionpage.md", "myothersectionpage Content.", "myothersectionpage Content Edited.").Build()
b.AssertFileContent("public/myothersection/myothersectionpage/index.html", "myothersectionpage Content Edited")
b.AssertRenderCountPage(1)
b.AssertRenderCountContent(1)
b.AssertRenderCountPage(2)
b.AssertRenderCountContent(2)
}

func TestRebuildRenameTextFileInBranchBundle(t *testing.T) {
Expand All @@ -171,7 +224,7 @@ func TestRebuildRenameTextFileInBranchBundle(t *testing.T) {

b.RenameFile("content/mysection/mysectiontext.txt", "content/mysection/mysectiontext2.txt").Build()
b.AssertFileContent("public/mysection/index.html", "mysectiontext2", "My Section")
b.AssertRenderCountPage(2)
b.AssertRenderCountPage(3)
b.AssertRenderCountContent(2)
}

Expand All @@ -181,14 +234,14 @@ func TestRebuildRenameTextFileInHomeBundle(t *testing.T) {

b.RenameFile("content/hometext.txt", "content/hometext2.txt").Build()
b.AssertFileContent("public/index.html", "hometext2", "Home Text Content.")
b.AssertRenderCountPage(3)
b.AssertRenderCountPage(5)
}

func TestRebuildRenameDirectoryWithLeafBundle(t *testing.T) {
b := TestRunning(t, rebuildFilesSimple)
b.RenameDir("content/mysection/mysectionbundle", "content/mysection/mysectionbundlerenamed").Build()
b.AssertFileContent("public/mysection/mysectionbundlerenamed/index.html", "My Section Bundle")
b.AssertRenderCountPage(1)
b.AssertRenderCountPage(2)
}

func TestRebuildRenameDirectoryWithBranchBundle(t *testing.T) {
Expand All @@ -197,7 +250,7 @@ func TestRebuildRenameDirectoryWithBranchBundle(t *testing.T) {
b.AssertFileContent("public/mysectionrenamed/index.html", "My Section")
b.AssertFileContent("public/mysectionrenamed/mysectionbundle/index.html", "My Section Bundle")
b.AssertFileContent("public/mysectionrenamed/mysectionbundle/mysectionbundletext.txt", "My Section Bundle Text 2 Content.")
b.AssertRenderCountPage(3)
b.AssertRenderCountPage(5)
}

func TestRebuildRenameDirectoryWithRegularPageUsedInHome(t *testing.T) {
Expand Down Expand Up @@ -296,7 +349,7 @@ func TestRebuildRenameDirectoryWithBranchBundleFastRender(t *testing.T) {
b.AssertFileContent("public/mysectionrenamed/index.html", "My Section")
b.AssertFileContent("public/mysectionrenamed/mysectionbundle/index.html", "My Section Bundle")
b.AssertFileContent("public/mysectionrenamed/mysectionbundle/mysectionbundletext.txt", "My Section Bundle Text 2 Content.")
b.AssertRenderCountPage(3)
b.AssertRenderCountPage(5)
}

func TestRebuilErrorRecovery(t *testing.T) {
Expand Down
4 changes: 4 additions & 0 deletions hugolib/shortcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,10 @@ func prepareShortcode(

// Allow the caller to delay the rendering of the shortcode if needed.
var fn shortcodeRenderFunc = func(ctx context.Context) ([]byte, bool, error) {
// A regular page's shortcode may be rendered by e.g. the home page,
// so we need to track any changes to this shortcode's page.
ctx = tpl.Context.DependencyManagerScopedProvider.Set(ctx, p)

if p.m.pageConfig.ContentMediaType.IsMarkdown() && sc.doMarkup {
// Signal downwards that the content rendered will be
// parsed and rendered by Goldmark.
Expand Down
1 change: 0 additions & 1 deletion tpl/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ type contextKey string
var Context = struct {
DependencyManagerScopedProvider hcontext.ContextDispatcher[identity.DependencyManagerScopedProvider]
GetDependencyManagerInCurrentScope func(context.Context) identity.Manager
SetDependencyManagerInCurrentScope func(context.Context, identity.Manager) context.Context
DependencyScope hcontext.ContextDispatcher[int]
Page hcontext.ContextDispatcher[page]
IsInGoldmark hcontext.ContextDispatcher[bool]
Expand Down

0 comments on commit c09ef5b

Please sign in to comment.