Skip to content

Commit

Permalink
Fix paginator refresh on server change
Browse files Browse the repository at this point in the history
  • Loading branch information
bep committed Apr 12, 2019
1 parent 7966c0b commit d991042
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 7 deletions.
77 changes: 77 additions & 0 deletions hugolib/hugo_sites_rebuild_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2019 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package hugolib

import (
"testing"
)

func TestSitesRebuild(t *testing.T) {

configFile := `
baseURL = "https://example.com"
title = "Rebuild this"
contentDir = "content"
`

contentFilename := "content/blog/page1.md"

b := newTestSitesBuilder(t).WithConfigFile("toml", configFile)

// To simulate https://github.com/gohugoio/hugo/issues/5838, the home page
// needs a content page.
b.WithContent("content/_index.md", `---
title: Home, Sweet Home!
---
`)

b.WithContent(contentFilename, `
---
title: "Page 1"
summary: "Initial summary"
paginate: 3
---
Content.
`)

b.WithTemplatesAdded("index.html", `
{{ range (.Paginate .Site.RegularPages).Pages }}
* Page: {{ .Title }}|Summary: {{ .Summary }}|Content: {{ .Content }}
{{ end }}
`)

b.Running().Build(BuildCfg{})

b.AssertFileContent("public/index.html", "* Page: Page 1|Summary: Initial summary|Content: <p>Content.</p>")

b.EditFiles(contentFilename, `
---
title: "Page 1 edit"
summary: "Edited summary"
---
Edited content.
`)

b.Build(BuildCfg{})

b.AssertFileContent("public/index.html", "* Page: Page 1 edit|Summary: Edited summary|Content: <p>Edited content.</p>")

}
6 changes: 6 additions & 0 deletions hugolib/page.go
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,12 @@ func (p *pageState) shiftToOutputFormat(idx int) error {
panic(fmt.Sprintf("pageOutput is nil for output idx %d", idx))
}

// Reset any built paginator. This will trigger when re-rendering pages in
// server mode.
if idx == 0 && p.pageOutput.paginator != nil && p.pageOutput.paginator.current != nil {
p.pageOutput.paginator.reset()
}

if idx > 0 {
// Check if we can reuse content from one of the previous formats.
for i := idx - 1; i >= 0; i-- {
Expand Down
2 changes: 1 addition & 1 deletion hugolib/page__output.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func newPageOutput(
var pag *pagePaginator

if render && ps.IsNode() {
pag = &pagePaginator{source: ps}
pag = newPagePaginator(ps)
paginatorProvider = pag
}

Expand Down
25 changes: 20 additions & 5 deletions hugolib/page__paginator.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,31 @@ import (
"github.com/gohugoio/hugo/resources/page"
)

type pagePaginator struct {
paginatorInit sync.Once
current *page.Pager
func newPagePaginator(source *pageState) *pagePaginator {
return &pagePaginator{
source: source,
pagePaginatorInit: &pagePaginatorInit{},
}
}

type pagePaginator struct {
*pagePaginatorInit
source *pageState
}

type pagePaginatorInit struct {
init sync.Once
current *page.Pager
}

// reset resets the paginator to allow for a rebuild.
func (p *pagePaginator) reset() {
p.pagePaginatorInit = &pagePaginatorInit{}
}

func (p *pagePaginator) Paginate(seq interface{}, options ...interface{}) (*page.Pager, error) {
var initErr error
p.paginatorInit.Do(func() {
p.init.Do(func() {
pagerSize, err := page.ResolvePagerSize(p.source.s.Cfg, options...)
if err != nil {
initErr = err
Expand Down Expand Up @@ -56,7 +71,7 @@ func (p *pagePaginator) Paginate(seq interface{}, options ...interface{}) (*page

func (p *pagePaginator) Paginator(options ...interface{}) (*page.Pager, error) {
var initErr error
p.paginatorInit.Do(func() {
p.init.Do(func() {
pagerSize, err := page.ResolvePagerSize(p.source.s.Cfg, options...)
if err != nil {
initErr = err
Expand Down
40 changes: 39 additions & 1 deletion hugolib/testhelpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"strings"
"text/template"

"github.com/fsnotify/fsnotify"
"github.com/gohugoio/hugo/common/herrors"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/deps"
Expand Down Expand Up @@ -45,6 +46,9 @@ type sitesBuilder struct {

dumper litter.Options

// Used to test partial rebuilds.
changedFiles []string

// Aka the Hugo server mode.
running bool

Expand Down Expand Up @@ -296,6 +300,19 @@ func (s *sitesBuilder) WithI18nAdded(filenameContent ...string) *sitesBuilder {
return s
}

func (s *sitesBuilder) EditFiles(filenameContent ...string) *sitesBuilder {
var changedFiles []string
for i := 0; i < len(filenameContent); i += 2 {
filename, content := filepath.FromSlash(filenameContent[i]), filenameContent[i+1]
changedFiles = append(changedFiles, filename)
writeSource(s.T, s.Fs, filename, content)

}
s.changedFiles = changedFiles

return s
}

func (s *sitesBuilder) writeFilePairs(folder string, filenameContent []string) *sitesBuilder {
if len(filenameContent)%2 != 0 {
s.Fatalf("expect filenameContent for %q in pairs (%d)", folder, len(filenameContent))
Expand Down Expand Up @@ -376,12 +393,33 @@ func (s *sitesBuilder) BuildFail(cfg BuildCfg) *sitesBuilder {
return s.build(cfg, true)
}

func (s *sitesBuilder) changeEvents() []fsnotify.Event {
if len(s.changedFiles) == 0 {
return nil
}

events := make([]fsnotify.Event, len(s.changedFiles))
// TODO(bep) remove?
for i, v := range s.changedFiles {
events[i] = fsnotify.Event{
Name: v,
Op: fsnotify.Write,
}
}

return events
}

func (s *sitesBuilder) build(cfg BuildCfg, shouldFail bool) *sitesBuilder {
defer func() {
s.changedFiles = nil
}()

if s.H == nil {
s.CreateSites()
}

err := s.H.Build(cfg)
err := s.H.Build(cfg, s.changeEvents()...)

if err == nil {
logErrorCount := s.H.NumLogErrors()
Expand Down

0 comments on commit d991042

Please sign in to comment.