URI: 
       node to page: Handle home - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit 734b6508a12b29444ec78fc07d3f3805cf06ea3c
   DIR parent e371ac0b6f56bdffe92b9e74dae571a003123912
  HTML Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Mon, 31 Oct 2016 10:23:01 +0100
       
       node to page: Handle home
       
       With refactored paginator handling.
       
       Updates #2297
       
       Diffstat:
         M hugolib/node_as_page_test.go        |      14 ++++++++++++++
         M hugolib/page.go                     |      94 +++++++++++++++++++++++++++++++
         M hugolib/pagination.go               |      17 ++++++-----------
         M hugolib/site.go                     |      65 +++++++++++++++----------------
       
       4 files changed, 145 insertions(+), 45 deletions(-)
       ---
   DIR diff --git 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")
       +
        }
   DIR diff --git 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
       +}
   DIR diff --git 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...)
        
   DIR diff --git 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
       +                        }
       +                }
                }
        }