mirror of
https://github.com/gohugoio/hugo.git
synced 2025-09-02 22:52:51 +02:00
Fix some change detection issues on server reloads
* Fix change detection when .GetPage/site.GetPage is used from shortcode * Fix stale content for GetPage results with short name lookups on server reloads Fixes #7623 Fixes #7624 Fixes #7625
This commit is contained in:
@@ -95,21 +95,23 @@ func newContentMap(cfg contentMapConfig) *contentMap {
|
||||
|
||||
m.pageReverseIndex = &contentTreeReverseIndex{
|
||||
t: []*contentTree{m.pages, m.sections, m.taxonomies},
|
||||
initFn: func(t *contentTree, m map[interface{}]*contentNode) {
|
||||
t.Walk(func(s string, v interface{}) bool {
|
||||
n := v.(*contentNode)
|
||||
if n.p != nil && !n.p.File().IsZero() {
|
||||
meta := n.p.File().FileInfo().Meta()
|
||||
if meta.Path() != meta.PathFile() {
|
||||
// Keep track of the original mount source.
|
||||
mountKey := filepath.ToSlash(filepath.Join(meta.Module(), meta.PathFile()))
|
||||
addToReverseMap(mountKey, n, m)
|
||||
contentTreeReverseIndexMap: &contentTreeReverseIndexMap{
|
||||
initFn: func(t *contentTree, m map[interface{}]*contentNode) {
|
||||
t.Walk(func(s string, v interface{}) bool {
|
||||
n := v.(*contentNode)
|
||||
if n.p != nil && !n.p.File().IsZero() {
|
||||
meta := n.p.File().FileInfo().Meta()
|
||||
if meta.Path() != meta.PathFile() {
|
||||
// Keep track of the original mount source.
|
||||
mountKey := filepath.ToSlash(filepath.Join(meta.Module(), meta.PathFile()))
|
||||
addToReverseMap(mountKey, n, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
k := strings.TrimPrefix(strings.TrimSuffix(path.Base(s), cmLeafSeparator), cmBranchSeparator)
|
||||
addToReverseMap(k, n, m)
|
||||
return false
|
||||
})
|
||||
k := strings.TrimPrefix(strings.TrimSuffix(path.Base(s), cmLeafSeparator), cmBranchSeparator)
|
||||
addToReverseMap(k, n, m)
|
||||
return false
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1030,12 +1032,21 @@ func (c *contentTreeRef) getSections() page.Pages {
|
||||
|
||||
type contentTreeReverseIndex struct {
|
||||
t []*contentTree
|
||||
m map[interface{}]*contentNode
|
||||
*contentTreeReverseIndexMap
|
||||
}
|
||||
|
||||
type contentTreeReverseIndexMap struct {
|
||||
m map[interface{}]*contentNode
|
||||
init sync.Once
|
||||
initFn func(*contentTree, map[interface{}]*contentNode)
|
||||
}
|
||||
|
||||
func (c *contentTreeReverseIndex) Reset() {
|
||||
c.contentTreeReverseIndexMap = &contentTreeReverseIndexMap{
|
||||
initFn: c.initFn,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *contentTreeReverseIndex) Get(key interface{}) *contentNode {
|
||||
c.init.Do(func() {
|
||||
c.m = make(map[interface{}]*contentNode)
|
||||
|
@@ -997,7 +997,6 @@ func (h *HugoSites) resetPageStateFromEvents(idset identity.Identities) {
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// Used in partial reloading to determine if the change is in a bundle.
|
||||
|
@@ -259,3 +259,66 @@ Output Shortcode AMP Edited
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// Issues #7623 #7625
|
||||
func TestSitesRebuildOnFilesIncludedWithGetPage(t *testing.T) {
|
||||
b := newTestSitesBuilder(t).Running()
|
||||
b.WithContent("pages/p1.md", `---
|
||||
title: p1
|
||||
---
|
||||
P3: {{< GetPage "pages/p3" >}}
|
||||
`)
|
||||
|
||||
b.WithContent("pages/p2.md", `---
|
||||
title: p2
|
||||
---
|
||||
P4: {{< site_GetPage "pages/p4" >}}
|
||||
P5: {{< site_GetPage "p5" >}}
|
||||
P6: {{< dot_site_GetPage "p6" >}}
|
||||
`)
|
||||
|
||||
b.WithContent("pages/p3/index.md", "---\ntitle: p3\nheadless: true\n---\nP3 content")
|
||||
b.WithContent("pages/p4/index.md", "---\ntitle: p4\nheadless: true\n---\nP4 content")
|
||||
b.WithContent("pages/p5.md", "---\ntitle: p5\n---\nP5 content")
|
||||
b.WithContent("pages/p6.md", "---\ntitle: p6\n---\nP6 content")
|
||||
|
||||
b.WithTemplates(
|
||||
"_default/single.html", `{{ .Content }}`,
|
||||
"shortcodes/GetPage.html", `
|
||||
{{ $arg := .Get 0 }}
|
||||
{{ $p := .Page.GetPage $arg }}
|
||||
{{ $p.Content }}
|
||||
`,
|
||||
"shortcodes/site_GetPage.html", `
|
||||
{{ $arg := .Get 0 }}
|
||||
{{ $p := site.GetPage $arg }}
|
||||
{{ $p.Content }}
|
||||
`, "shortcodes/dot_site_GetPage.html", `
|
||||
{{ $arg := .Get 0 }}
|
||||
{{ $p := .Site.GetPage $arg }}
|
||||
{{ $p.Content }}
|
||||
`,
|
||||
)
|
||||
|
||||
b.Build(BuildCfg{})
|
||||
|
||||
b.AssertFileContent("public/pages/p1/index.html", "P3 content")
|
||||
b.AssertFileContent("public/pages/p2/index.html", `P4 content
|
||||
P5 content
|
||||
P6 content
|
||||
`)
|
||||
|
||||
b.EditFiles("content/pages/p3/index.md", "---\ntitle: p3\n---\nP3 changed content")
|
||||
b.EditFiles("content/pages/p4/index.md", "---\ntitle: p4\n---\nP4 changed content")
|
||||
b.EditFiles("content/pages/p5.md", "---\ntitle: p5\n---\nP5 changed content")
|
||||
b.EditFiles("content/pages/p6.md", "---\ntitle: p6\n---\nP6 changed content")
|
||||
|
||||
b.Build(BuildCfg{})
|
||||
|
||||
b.AssertFileContent("public/pages/p1/index.html", "P3 changed content")
|
||||
b.AssertFileContent("public/pages/p2/index.html", `P4 changed content
|
||||
P5 changed content
|
||||
P6 changed content
|
||||
`)
|
||||
|
||||
}
|
||||
|
@@ -78,6 +78,7 @@ type pageContext interface {
|
||||
posOffset(offset int) text.Position
|
||||
wrapError(err error) error
|
||||
getContentConverter() converter.Converter
|
||||
addDependency(dep identity.Provider)
|
||||
}
|
||||
|
||||
// wrapErr adds some context to the given error if possible.
|
||||
@@ -93,6 +94,18 @@ type pageSiteAdapter struct {
|
||||
s *Site
|
||||
}
|
||||
|
||||
func (pa pageSiteAdapter) GetPageWithTemplateInfo(info tpl.Info, ref string) (page.Page, error) {
|
||||
p, err := pa.GetPage(ref)
|
||||
if p != nil {
|
||||
// Track pages referenced by templates/shortcodes
|
||||
// when in server mode.
|
||||
if im, ok := info.(identity.Manager); ok {
|
||||
im.Add(p)
|
||||
}
|
||||
}
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (pa pageSiteAdapter) GetPage(ref string) (page.Page, error) {
|
||||
p, err := pa.s.getPageNew(pa.p, ref)
|
||||
if p == nil {
|
||||
@@ -127,6 +140,10 @@ func (p *pageState) Eq(other interface{}) bool {
|
||||
return p == pp
|
||||
}
|
||||
|
||||
func (p *pageState) GetIdentity() identity.Identity {
|
||||
return identity.NewPathIdentity(files.ComponentFolderContent, filepath.FromSlash(p.Path()))
|
||||
}
|
||||
|
||||
func (p *pageState) GitInfo() *gitmap.GitInfo {
|
||||
return p.gitInfo
|
||||
}
|
||||
|
@@ -1538,6 +1538,7 @@ func (s *Site) resetBuildState(sourceChanged bool) {
|
||||
s.init.Reset()
|
||||
|
||||
if sourceChanged {
|
||||
s.pageMap.contentMap.pageReverseIndex.Reset()
|
||||
s.PageCollections = newPageCollections(s.pageMap)
|
||||
s.pageMap.withEveryBundlePage(func(p *pageState) bool {
|
||||
p.pagePages = &pagePages{}
|
||||
@@ -1587,6 +1588,18 @@ func (s *SiteInfo) GetPage(ref ...string) (page.Page, error) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (s *SiteInfo) GetPageWithTemplateInfo(info tpl.Info, ref ...string) (page.Page, error) {
|
||||
p, err := s.GetPage(ref...)
|
||||
if p != nil {
|
||||
// Track pages referenced by templates/shortcodes
|
||||
// when in server mode.
|
||||
if im, ok := info.(identity.Manager); ok {
|
||||
im.Add(p)
|
||||
}
|
||||
}
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (s *Site) permalink(link string) string {
|
||||
return s.PathSpec.PermalinkForBaseURL(link, s.PathSpec.BaseURL.String())
|
||||
}
|
||||
|
@@ -599,7 +599,7 @@ title: P1
|
||||
|
||||
idset := make(map[identity.Identity]bool)
|
||||
collectIdentities(idset, templ.(tpl.Info))
|
||||
b.Assert(idset, qt.HasLen, 10)
|
||||
b.Assert(idset, qt.HasLen, 11)
|
||||
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user