Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2016-10-31 12:23:01 +0300
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2016-11-22 11:57:03 +0300
commit734b6508a12b29444ec78fc07d3f3805cf06ea3c (patch)
treeb91365eab9f68ac7c9864e5d98c8cde34b7b14d5 /hugolib
parente371ac0b6f56bdffe92b9e74dae571a003123912 (diff)
node to page: Handle home
With refactored paginator handling. Updates #2297
Diffstat (limited to 'hugolib')
-rw-r--r--hugolib/node_as_page_test.go14
-rw-r--r--hugolib/page.go94
-rw-r--r--hugolib/pagination.go17
-rw-r--r--hugolib/site.go65
4 files changed, 145 insertions, 45 deletions
diff --git a/hugolib/node_as_page_test.go b/hugolib/node_as_page_test.go
index 0bbc99fd8..722e5990c 100644
--- a/hugolib/node_as_page_test.go
+++ b/hugolib/node_as_page_test.go
@@ -18,6 +18,7 @@ import (
"path/filepath"
"testing"
+ "github.com/spf13/viper"
"github.com/stretchr/testify/require"
)
@@ -54,6 +55,9 @@ Home **Content!**
Index Title: {{ .Title }}
Index Content: {{ .Content }}
# Pages: {{ len .Data.Pages }}
+{{ range .Paginator.Pages }}
+ Pag: {{ .Title }}
+{{ end }}
`)
writeSource(t, filepath.Join("layouts", "_default", "single.html"), `
@@ -70,6 +74,8 @@ Content Page %d
`, i, i))
}
+ viper.Set("paginate", 3)
+
s := newSiteDefaultLang()
if err := buildAndRenderSite(s); err != nil {
@@ -80,6 +86,7 @@ Content Page %d
"Index Title: Home Sweet Home!",
"Home <strong>Content!</strong>",
"# Pages: 10")
+
assertFileContent(t, filepath.Join("public", "regular1", "index.html"), false, "Single Title: Page 1", "Content Page 1")
h := s.owner
@@ -100,4 +107,11 @@ Content Page %d
require.False(t, first.IsNode())
require.True(t, first.IsPage())
+ first.Paginator()
+
+ // Check paginator
+ assertFileContent(t, filepath.Join("public", "page", "3", "index.html"), false,
+ "Pag: Page 6",
+ "Pag: Page 7")
+
}
diff --git a/hugolib/page.go b/hugolib/page.go
index 4c4b0d29e..87f50fc91 100644
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -1173,3 +1173,97 @@ func (p *Page) TargetPath() (outfile string) {
return p.addLangFilepathPrefix(filepath.Join(strings.ToLower(
p.Site.pathSpec.MakePath(p.Source.Dir())), strings.TrimSpace(outfile)))
}
+
+// Pre render prepare steps
+
+func (p *Page) prepareLayouts() error {
+ // TODO(bep): Check the IsRenderable logic.
+ if p.NodeType == NodePage {
+ var layouts []string
+ if !p.IsRenderable() {
+ self := "__" + p.TargetPath()
+ _, err := p.Site.owner.tmpl.GetClone().New(self).Parse(string(p.Content))
+ if err != nil {
+ return err
+ }
+ layouts = append(layouts, self)
+ } else {
+ layouts = append(layouts, p.layouts()...)
+ layouts = append(layouts, "_default/single.html")
+ }
+ p.layoutsCalculated = layouts
+ }
+ return nil
+}
+
+func (p *Page) prepareData() error {
+ switch p.NodeType {
+ case NodePage:
+ case NodeHome:
+ p.Data = make(map[string]interface{})
+ // TODO(bep) np cache the below
+ // TODO(bep) np
+ p.Data["Pages"] = p.Site.owner.findPagesByNodeType(NodePage)
+ }
+
+ return nil
+}
+
+// renderPaginator must be run after the owning Page has been rendered.
+// TODO(bep) np
+func (p *Page) renderPaginator(s *Site) error {
+ if p.paginator != nil {
+ paginatePath := helpers.Config().GetString("paginatePath")
+
+ {
+ // write alias for page 1
+ // TODO(bep) ml all of these n.addLang ... fix.
+ permaLink, _ := p.Permalink()
+ s.writeDestAlias(p.addLangPathPrefix(helpers.PaginateAliasPath("", 1)), permaLink, nil)
+ }
+
+ pagers := p.paginator.Pagers()
+
+ for i, pager := range pagers {
+ if i == 0 {
+ // already created
+ continue
+ }
+
+ pagerNode := p.copy()
+
+ pagerNode.paginator = pager
+ if pager.TotalPages() > 0 {
+ first, _ := pager.page(0)
+ pagerNode.Date = first.Date
+ pagerNode.Lastmod = first.Lastmod
+ }
+
+ pageNumber := i + 1
+ htmlBase := fmt.Sprintf("/%s/%d", paginatePath, pageNumber)
+ htmlBase = p.addLangPathPrefix(htmlBase)
+ if err := s.renderAndWritePage(pagerNode.Title,
+ filepath.FromSlash(htmlBase), pagerNode, p.layouts()...); err != nil {
+ return err
+ }
+
+ }
+ }
+ return nil
+}
+
+// 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
+func (p *Page) copy() *Page {
+ c := &Page{Node: Node{NodeType: p.NodeType}}
+ 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
+}
diff --git a/hugolib/pagination.go b/hugolib/pagination.go
index 81f3e0cda..65790d6ee 100644
--- a/hugolib/pagination.go
+++ b/hugolib/pagination.go
@@ -260,7 +260,9 @@ func splitPageGroups(pageGroups PagesGroup, size int) []paginatedElement {
// Paginator gets this Node's paginator if it's already created.
// If it's not, one will be created with all pages in Data["Pages"].
func (n *Node) Paginator(options ...interface{}) (*Pager, error) {
-
+ if !n.NodeType.IsNode() {
+ return nil, errors.New("Paginators not supported for content pages.")
+ }
pagerSize, err := resolvePagerSize(options...)
if err != nil {
@@ -297,20 +299,13 @@ func (n *Node) Paginator(options ...interface{}) (*Pager, error) {
return n.paginator, nil
}
-// Paginator on Page isn't supported, calling this yields an error.
-func (p *Page) Paginator(options ...interface{}) (*Pager, error) {
- return nil, errors.New("Paginators not supported for content pages.")
-}
-
-// Paginate on Page isn't supported, calling this yields an error.
-func (p *Page) Paginate(seq interface{}, options ...interface{}) (*Pager, error) {
- return nil, errors.New("Paginators not supported for content pages.")
-}
-
// Paginate gets this Node's paginator if it's already created.
// If it's not, one will be created with the qiven sequence.
// Note that repeated calls will return the same result, even if the sequence is different.
func (n *Node) Paginate(seq interface{}, options ...interface{}) (*Pager, error) {
+ if !n.NodeType.IsNode() {
+ return nil, errors.New("Paginators not supported for content pages.")
+ }
pagerSize, err := resolvePagerSize(options...)
diff --git a/hugolib/site.go b/hugolib/site.go
index 55749aeb5..7d7ac438b 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -848,9 +848,15 @@ func (s *Site) render() (err error) {
return
}
s.timerStep("render and write lists")
+
+ if err = s.preparePages(); err != nil {
+ return
+ }
+
if err = s.renderPages(); err != nil {
return
}
+
s.timerStep("render and write pages")
if err = s.renderHomePage(false); err != nil {
return
@@ -1620,6 +1626,25 @@ func (s *Site) renderAliases() error {
return nil
}
+func (s *Site) preparePages() error {
+ var errors []error
+
+ for _, p := range s.Pages {
+ if err := p.prepareLayouts(); err != nil {
+ errors = append(errors, err)
+ }
+ if err := p.prepareData(); err != nil {
+ errors = append(errors, err)
+ }
+ }
+
+ if len(errors) != 0 {
+ return fmt.Errorf("Prepare pages failed: %.100q…", errors)
+ }
+
+ return nil
+}
+
// renderPages renders pages each corresponding to a markdown file.
func (s *Site) renderPages() error {
@@ -1631,26 +1656,6 @@ func (s *Site) renderPages() error {
procs := getGoMaxProcs()
- // this cannot be fanned out to multiple Go routines
- // See issue #1601
- // TODO(bep): Check the IsRenderable logic.
- for _, p := range s.Pages {
- var layouts []string
- if !p.IsRenderable() {
- self := "__" + p.TargetPath()
- _, err := s.owner.tmpl.GetClone().New(self).Parse(string(p.Content))
- if err != nil {
- results <- err
- continue
- }
- layouts = append(layouts, self)
- } else {
- layouts = append(layouts, p.layouts()...)
- layouts = append(layouts, "_default/single.html")
- }
- p.layoutsCalculated = layouts
- }
-
wg := &sync.WaitGroup{}
for i := 0; i < procs*4; i++ {
@@ -1678,23 +1683,15 @@ func (s *Site) renderPages() error {
func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.WaitGroup) {
defer wg.Done()
for p := range pages {
- // TODO(bep) np paginator
- s.preparePage(p)
- err := s.renderAndWritePage("page "+p.FullFilePath(), p.TargetPath(), p, s.appendThemeTemplates(p.layouts())...)
- if err != nil {
+ if err := s.renderAndWritePage("page "+p.FullFilePath(), p.TargetPath(), p, s.appendThemeTemplates(p.layouts())...); err != nil {
results <- err
}
- }
-}
-func (s *Site) preparePage(p *Page) {
- // TODO(bep) np the order of it all
- switch p.NodeType {
- case NodePage:
- case NodeHome:
- p.Data = make(map[string]interface{})
- // TODO(bep) np cache the below
- p.Data["Pages"] = s.owner.findPagesByNodeType(NodePage)
+ if p.NodeType.IsNode() {
+ if err := p.renderPaginator(s); err != nil {
+ results <- err
+ }
+ }
}
}