From: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date: Tue, 22 Feb 2022 13:42:33 +0000 (+0100)
Subject: Add page.Store
X-Git-Tag: v0.93.0~36
X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=e97d3c640fc5e845135c5f8f49ff11e23cffddeb;p=brevno-suite%2Fhugo

Add page.Store

Fixes #9546
---

diff --git a/hugolib/page__common.go b/hugolib/page__common.go
index bf11ae7d..0294393e 100644
--- a/hugolib/page__common.go
+++ b/hugolib/page__common.go
@@ -60,6 +60,9 @@ type pageCommon struct {
 	// Lazily initialized dependencies.
 	init *lazy.Init
 
+	// Store holds state that survives server rebuilds.
+	store *maps.Scratch
+
 	// All of these represents the common parts of a page.Page
 	maps.Scratcher
 	navigation.PageMenusProvider
@@ -134,6 +137,10 @@ type pageCommon struct {
 	forceRender bool
 }
 
+func (p *pageCommon) Store() *maps.Scratch {
+	return p.store
+}
+
 type pagePages struct {
 	pagesInit sync.Once
 	pages     page.Pages
diff --git a/hugolib/page__new.go b/hugolib/page__new.go
index 5efebe4f..91847784 100644
--- a/hugolib/page__new.go
+++ b/hugolib/page__new.go
@@ -41,6 +41,7 @@ func newPageBase(metaProvider *pageMeta) (*pageState, error) {
 			FileProvider:            metaProvider,
 			AuthorProvider:          metaProvider,
 			Scratcher:               maps.NewScratcher(),
+			store:                   maps.NewScratch(),
 			Positioner:              page.NopPage,
 			InSectionPositioner:     page.NopPage,
 			ResourceMetaProvider:    metaProvider,
diff --git a/hugolib/page_test.go b/hugolib/page_test.go
index 6b35e481..1edef622 100644
--- a/hugolib/page_test.go
+++ b/hugolib/page_test.go
@@ -1769,7 +1769,7 @@ Summary: In Chinese, 好 means good.
 	b.AssertFileContent("public/p6/index.html", "WordCount: 7\nFuzzyWordCount: 100\nReadingTime: 1\nLen Plain: 638\nLen PlainWords: 7\nTruncated: false\nLen Summary: 637\nLen Content: 652")
 }
 
-func TestScratchSite(t *testing.T) {
+func TestScratch(t *testing.T) {
 	t.Parallel()
 
 	b := newTestSitesBuilder(t)
@@ -1796,6 +1796,50 @@ title: Scratch Me!
 	b.AssertFileContent("public/scratchme/index.html", "C: cv")
 }
 
+func TestScratchRebuild(t *testing.T) {
+	t.Parallel()
+
+	files := `
+-- config.toml --
+-- content/p1.md --
+---
+title: "p1"
+---
+{{< scratchme >}}
+-- layouts/shortcodes/foo.html --
+notused
+-- layouts/shortcodes/scratchme.html --
+{{ .Page.Scratch.Set "scratch" "foo" }}
+{{ .Page.Store.Set "scratch" "bar" }}
+-- layouts/_default/single.html --
+{{ .Content }}
+Scratch: {{ .Scratch.Get "scratch" }}|
+Store: {{ .Store.Get "scratch" }}|
+`
+
+	b := NewIntegrationTestBuilder(
+		IntegrationTestConfig{
+			T:           t,
+			TxtarString: files,
+			Running:     true,
+		},
+	).Build()
+
+	b.AssertFileContent("public/p1/index.html", `
+Scratch: foo|
+Store: bar|
+	`)
+
+	b.EditFiles("layouts/shortcodes/foo.html", "edit")
+
+	b.Build()
+
+	b.AssertFileContent("public/p1/index.html", `
+Scratch: |
+Store: bar|
+	`)
+}
+
 func TestPageParam(t *testing.T) {
 	t.Parallel()
 
diff --git a/resources/page/page.go b/resources/page/page.go
index d1790806..1ad536e9 100644
--- a/resources/page/page.go
+++ b/resources/page/page.go
@@ -261,7 +261,15 @@ type PageWithoutContent interface {
 	// Helper methods
 	ShortcodeInfoProvider
 	compare.Eqer
+
+	// Scratch returns a Scratch that can be used to store temporary state.
+	// Note that this Scratch gets reset on server rebuilds. See Store() for a variant that survives.
 	maps.Scratcher
+
+	// Store returns a Scratch that can be used to store temporary state.
+	// In contrast to Scratch(), this Scratch is not reset on server rebuilds.
+	Store() *maps.Scratch
+
 	RelatedKeywordsProvider
 
 	// GetTerms gets the terms of a given taxonomy,
diff --git a/resources/page/page_nop.go b/resources/page/page_nop.go
index 011fabfc..fd706f99 100644
--- a/resources/page/page_nop.go
+++ b/resources/page/page_nop.go
@@ -418,6 +418,10 @@ func (p *nopPage) Scratch() *maps.Scratch {
 	return nil
 }
 
+func (p *nopPage) Store() *maps.Scratch {
+	return nil
+}
+
 func (p *nopPage) RelatedKeywords(cfg related.IndexConfig) ([]related.Keyword, error) {
 	return nil, nil
 }
diff --git a/resources/page/testhelpers_test.go b/resources/page/testhelpers_test.go
index 57077ecf..df4e79db 100644
--- a/resources/page/testhelpers_test.go
+++ b/resources/page/testhelpers_test.go
@@ -498,6 +498,10 @@ func (p *testPage) Scratch() *maps.Scratch {
 	panic("not implemented")
 }
 
+func (p *testPage) Store() *maps.Scratch {
+	panic("not implemented")
+}
+
 func (p *testPage) RelatedKeywords(cfg related.IndexConfig) ([]related.Keyword, error) {
 	v, err := p.Param(cfg.Name)
 	if err != nil {