URI: 
       Fix server edits of resources included in shortcode/hooks - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit c1dc35dd712fc926cc7eaa2bf607fb4716794dfd
   DIR parent fc3d1cbadb48d5f8e10fcd811377de6b8453ea8d
  HTML Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Fri, 29 Nov 2024 12:13:49 +0100
       
       Fix server edits of resources included in shortcode/hooks
       
       Fixes #13093
       
       Diffstat:
         M hugolib/page__content.go            |       4 ++++
         M hugolib/rebuild_test.go             |      77 ++++++++++++++++++++++++++-----
         M identity/finder.go                  |      25 ++++++++++++++++---------
         M tpl/template.go                     |       1 -
       
       4 files changed, 86 insertions(+), 21 deletions(-)
       ---
   DIR diff --git a/hugolib/page__content.go b/hugolib/page__content.go
       @@ -863,6 +863,10 @@ type cachedContentScope struct {
        }
        
        func (c *cachedContentScope) prepareContext(ctx context.Context) context.Context {
       +        // A regular page's shortcode etc. may be rendered by e.g. the home page,
       +        // so we need to track any changes to this content's 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
   DIR diff --git a/hugolib/rebuild_test.go b/hugolib/rebuild_test.go
       @@ -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 --
       @@ -58,6 +63,21 @@ Home Text Content.
        title: "myothersectionpage"
        ---
        myothersectionpage Content.
       +-- content/mythirdsection/mythirdsectionpage.md --
       +---
       +title: "mythirdsectionpage"
       +---
       +mythirdsectionpage Content.
       +{{< myshortcodetext >}}
       +§§§ myothertext
       +foo
       +§§§
       +-- assets/mytext.txt --
       +Assets My Text.
       +-- assets/myshortcodetext.txt --
       +Assets My Shortcode Text.
       +-- assets/myothertext.txt --
       +Assets My Other Text.
        -- layouts/_default/single.html --
        Single: {{ .Title }}|{{ .Content }}$
        Resources: {{ range $i, $e := .Resources }}{{ $i }}:{{ .RelPermalink }}|{{ .Content }}|{{ end }}$
       @@ -68,6 +88,13 @@ Len Resources: {{ len .Resources }}|
        Resources: {{ range $i, $e := .Resources }}{{ $i }}:{{ .RelPermalink }}|{{ .Content }}|{{ end }}$
        -- layouts/shortcodes/foo.html --
        Foo.
       +-- layouts/shortcodes/myshortcodetext.html --
       +{{ warnf "mytext %s" now}}
       +{{ $r := resources.Get "myshortcodetext.txt" }}
       +My Shortcode Text: {{ $r.Content }}|{{ $r.Permalink }}|
       +-- layouts/_default/_markup/render-codeblock-myothertext.html --
       +{{ $r := resources.Get "myothertext.txt" }}
       +My Other Text: {{ $r.Content }}|{{ $r.Permalink }}|
        
        `
        
       @@ -83,6 +110,34 @@ func TestRebuildEditTextFileInLeafBundle(t *testing.T) {
                b.AssertRenderCountContent(1)
        }
        
       +func TestRebuildEditTextFileInShortcode(t *testing.T) {
       +        t.Parallel()
       +        for i := 0; i < 3; i++ {
       +                b := TestRunning(t, rebuildFilesSimple)
       +                b.AssertFileContent("public/mythirdsection/mythirdsectionpage/index.html",
       +                        "Text: Assets My Shortcode Text.")
       +                b.EditFileReplaceAll("assets/myshortcodetext.txt", "My Shortcode Text", "My Shortcode Text Edited").Build()
       +                fmt.Println(b.LogString())
       +                b.AssertFileContent("public/mythirdsection/mythirdsectionpage/index.html",
       +                        "Text: Assets My Shortcode Text Edited.")
       +
       +        }
       +}
       +
       +func TestRebuildEditTextFileInHook(t *testing.T) {
       +        t.Parallel()
       +        for i := 0; i < 3; i++ {
       +                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("public/mythirdsection/mythirdsectionpage/index.html",
       +                        "Text: Assets My Other Text Edited.")
       +
       +        }
       +}
       +
        func TestRebuiEditUnmarshaledYamlFileInLeafBundle(t *testing.T) {
                files := `
        -- hugo.toml --
       @@ -140,8 +195,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)
                })
        }
        
       @@ -161,8 +216,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) {
       @@ -171,7 +226,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)
        }
        
       @@ -181,14 +236,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) {
       @@ -197,7 +252,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) {
       @@ -296,7 +351,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) {
       @@ -1239,7 +1294,7 @@ Single.
                        return strings.Replace(s, "red", "blue", 1)
                }).Build()
        
       -        b.AssertRenderCountPage(3)
       +        b.AssertRenderCountPage(4)
        
                b.AssertFileContent("public/index.html", "Home.", "<style>body {\n\tbackground: blue;\n}</style>")
        }
   DIR diff --git a/identity/finder.go b/identity/finder.go
       @@ -122,17 +122,21 @@ func (f *Finder) Contains(id, in Identity, maxDepth int) FinderResult {
        
                defer putSearchID(sid)
        
       -        if r := f.checkOne(sid, in, 0); r > 0 {
       +        r := FinderNotFound
       +        if i := f.checkOne(sid, in, 0); i > r {
       +                r = i
       +        }
       +        if r == FinderFound {
                        return r
                }
        
                m := GetDependencyManager(in)
                if m != nil {
       -                if r := f.checkManager(sid, m, 0); r > 0 {
       -                        return r
       +                if i := f.checkManager(sid, m, 0); i > r {
       +                        r = i
                        }
                }
       -        return FinderNotFound
       +        return r
        }
        
        func (f *Finder) checkMaxDepth(sid *searchID, level int) FinderResult {
       @@ -279,15 +283,18 @@ func (f *Finder) search(sid *searchID, m Manager, depth int) FinderResult {
                var r FinderResult
                m.forEeachIdentity(
                        func(v Identity) bool {
       -                        if r > 0 {
       -                                panic("should be terminated")
       +                        i := f.checkOne(sid, v, depth)
       +                        if i > r {
       +                                r = i
                                }
       -                        r = f.checkOne(sid, v, depth)
       -                        if r > 0 {
       +                        if r == FinderFound {
                                        return true
                                }
                                m := GetDependencyManager(v)
       -                        if r = f.checkManager(sid, m, depth+1); r > 0 {
       +                        if i := f.checkManager(sid, m, depth+1); i > r {
       +                                r = i
       +                        }
       +                        if r == FinderFound {
                                        return true
                                }
                                return false
   DIR diff --git a/tpl/template.go b/tpl/template.go
       @@ -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]