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
This commit is contained in:
Bjørn Erik Pedersen 2016-11-16 20:32:38 +01:00
parent 62e9e7e6ba
commit 99d11386a7
6 changed files with 32 additions and 30 deletions

View file

@ -304,6 +304,7 @@ func (h *HugoSites) createMissingPages() error {
// 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,

View file

@ -70,6 +70,7 @@ const (
)
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 @@ type Page struct {
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,14 +193,24 @@ type Page struct {
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,
@ -231,7 +238,6 @@ type PageMeta struct {
wordCount int
fuzzyWordCount int
readingTime int
pageMetaInit sync.Once
Weight int
}
@ -532,6 +538,7 @@ func (p *Page) getRenderingConfig() *helpers.Blackfriday {
func newPage(filename string) *Page {
page := Page{
pageInit: &pageInit{},
Kind: kindFromFilename(filename),
contentType: "",
Source: Source{File: *source.NewFile(filename)},
@ -1538,20 +1545,12 @@ func (p *Page) updatePageDates() {
}
}
// 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

View file

@ -147,7 +147,7 @@ func createSortTestPages(num int) Pages {
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),

View file

@ -66,7 +66,8 @@ func TestPermalink(t *testing.T) {
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,

View file

@ -1269,7 +1269,7 @@ func TestIndexPageSimpleMethods(t *testing.T) {
{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) {

View file

@ -457,6 +457,7 @@ func createTestPages(num int) Pages {
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),