ref: 99d11386a7de544f044f30782310175cf2df4004
parent: 62e9e7e6ba3eee386c95d0420386132ad8acaa7e
author: Bjørn Erik Pedersen <[email protected]>
date: Wed Nov 16 15:32:38 EST 2016
node to page: Fix the Page copy() By embeding the init sync.Once var in a pointer so we can reset it when we copy the page. Updates #2297
--- a/hugolib/hugo_sites.go
+++ b/hugolib/hugo_sites.go
@@ -304,6 +304,7 @@
// Move the new* methods after cleanup in site.go
func (s *Site) newNodePage(typ string) *Page {
return &Page{
+ pageInit: &pageInit{},
Kind: typ,
Data: make(map[string]interface{}),
Site: &s.Info,
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -70,6 +70,7 @@
)
type Page struct {
+ *pageInit
// Kind is the discriminator that identifies the different page types
// in the different page collections. This can, as an example, be used
@@ -145,18 +146,14 @@
shortcodes map[string]shortcode
// the content stripped for HTML
- plain string // TODO should be []byte
- plainWords []string
- plainInit sync.Once
- plainWordsInit sync.Once
+ plain string // TODO should be []byte
+ plainWords []string
// rendering configuration
- renderingConfig *helpers.Blackfriday
- renderingConfigInit sync.Once
+ renderingConfig *helpers.Blackfriday
// menus
- pageMenus PageMenus
- pageMenusInit sync.Once
+ pageMenus PageMenus
Source
@@ -196,16 +193,26 @@
URLPath
- paginator *Pager
- paginatorInit sync.Once
+ paginator *Pager
scratch *Scratch
- language *helpers.Language
- languageInit sync.Once
- lang string
+ language *helpers.Language
+ lang string
}
+// pageInit lazy initializes different parts of the page. It is extracted
+// into its own type so we can easily create a copy of a given page.
+type pageInit struct {
+ languageInit sync.Once
+ pageMenusInit sync.Once
+ pageMetaInit sync.Once
+ paginatorInit sync.Once
+ plainInit sync.Once
+ plainWordsInit sync.Once
+ renderingConfigInit sync.Once
+}
+
// IsNode returns whether this is an item of one of the list types in Hugo,
// i.e. not a regular content page.
func (p *Page) IsNode() bool {
@@ -231,7 +238,6 @@
wordCount int
fuzzyWordCount int
readingTime int
- pageMetaInit sync.Once
Weight int
}
@@ -532,6 +538,7 @@
func newPage(filename string) *Page {
page := Page{
+ pageInit: &pageInit{},
Kind: kindFromFilename(filename),
contentType: "",
Source: Source{File: *source.NewFile(filename)},
@@ -1538,20 +1545,12 @@
}
}
-// Page constains some sync.Once which have a mutex, so we cannot just
-// copy the Page by value. So for the situations where we need a copy,
-// the paginators etc., we do it manually here.
-// TODO(bep) np do better
+// copy creates a copy of this page with the lazy sync.Once vars reset
+// so they will be evaluated again, for word count calculations etc.
func (p *Page) copy() *Page {
- c := &Page{Kind: p.Kind, Site: p.Site}
- c.Title = p.Title
- c.Data = p.Data
- c.Date = p.Date
- c.Lastmod = p.Lastmod
- c.language = p.language
- c.lang = p.lang
- c.URLPath = p.URLPath
- return c
+ c := *p
+ c.pageInit = &pageInit{}
+ return &c
}
// TODO(bep) np these are pulled over from Node. Needs regrouping / embed
--- a/hugolib/pageSort_test.go
+++ b/hugolib/pageSort_test.go
@@ -147,7 +147,7 @@
for i := 0; i < num; i++ {
pages[i] = &Page{
-
+ pageInit: &pageInit{},
URLPath: URLPath{
Section: "z",
URL: fmt.Sprintf("http://base/x/y/p%d.html", i),
--- a/hugolib/page_permalink_test.go
+++ b/hugolib/page_permalink_test.go
@@ -66,7 +66,8 @@
info := newSiteInfo(siteBuilderCfg{baseURL: string(test.base), language: helpers.NewDefaultLanguage()})
p := &Page{
- Kind: KindPage,
+ pageInit: &pageInit{},
+ Kind: KindPage,
URLPath: URLPath{
Section: "z",
URL: test.url,
--- a/hugolib/page_test.go
+++ b/hugolib/page_test.go
@@ -1269,7 +1269,7 @@
{func(n *Page) bool { return n.Now().Unix() == time.Now().Unix() }},
} {
- n := &Page{Kind: KindHome}
+ n := &Page{pageInit: &pageInit{}, Kind: KindHome}
n.RSSLink = "rssLink"
if !this.assertFunc(n) {
--- a/hugolib/pagination_test.go
+++ b/hugolib/pagination_test.go
@@ -457,6 +457,7 @@
info := newSiteInfo(siteBuilderCfg{baseURL: "http://base/", language: helpers.NewDefaultLanguage()})
for i := 0; i < num; i++ {
pages[i] = &Page{
+ pageInit: &pageInit{},
URLPath: URLPath{
Section: "z",
URL: fmt.Sprintf("http://base/x/y/p%d.html", i),