node to page: Handle sections
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 31 Oct 2016 17:03:02 +0000 (18:03 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 22 Nov 2016 08:57:03 +0000 (09:57 +0100)
Updates #2297

hugolib/node.go
hugolib/node_as_page_test.go
hugolib/page.go
hugolib/permalinks.go
hugolib/site.go

index a3d9ca6997251713bd7330eddd4d02ca1f6838c6..c7c62093069e459b5cf65eddf9c3bc3552ccc279 100644 (file)
@@ -34,6 +34,7 @@ const (
 
        // The rest are node types; home page, sections etc.
        NodeHome
+       NodeSection
 )
 
 func (p NodeType) IsNode() bool {
@@ -338,8 +339,13 @@ func (n *Node) addLangFilepathPrefix(outfile string) string {
 
 func nodeTypeFromFilename(filename string) NodeType {
        // TODO(bep) np
-       if !strings.HasPrefix(filename, "_node") {
+       if !strings.Contains(filename, "_node") {
                return NodePage
        }
-       return NodeHome
+
+       if strings.HasPrefix(filename, "_node") {
+               return NodeHome
+       }
+
+       return NodeSection
 }
index 722e5990cf3cec9a486ce293e9f69a68a47ebe15..6d5c2fdb27ebaf895f5ab5e9b5e9b64da27b575b 100644 (file)
@@ -18,6 +18,7 @@ import (
        "path/filepath"
        "testing"
 
+       jww "github.com/spf13/jwalterweatherman"
        "github.com/spf13/viper"
        "github.com/stretchr/testify/require"
 )
@@ -29,7 +30,10 @@ import (
 
 */
 
-func TestHomeAsPage(t *testing.T) {
+func TestNodesAsPage(t *testing.T) {
+       //jww.SetStdoutThreshold(jww.LevelDebug)
+       jww.SetStdoutThreshold(jww.LevelFatal)
+
        nodePageFeatureFlag = true
        defer toggleNodePageFeatureFlag()
 
@@ -49,6 +53,18 @@ func TestHomeAsPage(t *testing.T) {
 title: Home Sweet Home!
 ---
 Home **Content!**
+`)
+
+       writeSource(t, filepath.Join("content", "sect1", "_node.md"), `---
+title: Section1
+---
+Section1 **Content!**
+`)
+
+       writeSource(t, filepath.Join("content", "sect2", "_node.md"), `---
+title: Section2
+---
+Section2 **Content!**
 `)
 
        writeSource(t, filepath.Join("layouts", "index.html"), `
@@ -63,18 +79,32 @@ Index Content: {{ .Content }}
        writeSource(t, filepath.Join("layouts", "_default", "single.html"), `
 Single Title: {{ .Title }}
 Single Content: {{ .Content }}
+`)
+
+       writeSource(t, filepath.Join("layouts", "_default", "section.html"), `
+Section Title: {{ .Title }}
+Section Content: {{ .Content }}
+# Pages: {{ len .Data.Pages }}
+{{ range .Paginator.Pages }}
+       Pag: {{ .Title }}
+{{ end }}
 `)
 
        // Add some regular pages
-       for i := 0; i < 10; i++ {
-               writeSource(t, filepath.Join("content", fmt.Sprintf("regular%d.md", i)), fmt.Sprintf(`---
-title: Page %d
+       for i := 1; i <= 4; i++ {
+               sect := "sect1"
+               if i > 2 {
+                       sect = "sect2"
+               }
+               writeSource(t, filepath.Join("content", sect, fmt.Sprintf("regular%d.md", i)), fmt.Sprintf(`---
+title: Page %02d
+categories: Hugo
 ---
-Content Page %d
+Content Page %02d
 `, i, i))
        }
 
-       viper.Set("paginate", 3)
+       viper.Set("paginate", 1)
 
        s := newSiteDefaultLang()
 
@@ -85,9 +115,9 @@ Content Page %d
        assertFileContent(t, filepath.Join("public", "index.html"), false,
                "Index Title: Home Sweet Home!",
                "Home <strong>Content!</strong>",
-               "# Pages: 10")
+               "# Pages: 4")
 
-       assertFileContent(t, filepath.Join("public", "regular1", "index.html"), false, "Single Title: Page 1", "Content Page 1")
+       assertFileContent(t, filepath.Join("public", "sect1", "regular1", "index.html"), false, "Single Title: Page 01", "Content Page 01")
 
        h := s.owner
        nodes := h.findPagesByNodeType(NodeHome)
@@ -100,7 +130,7 @@ Content Page %d
        require.False(t, home.IsPage())
 
        pages := h.findPagesByNodeType(NodePage)
-       require.Len(t, pages, 10)
+       require.Len(t, pages, 4)
 
        first := pages[0]
        require.False(t, first.IsHome())
@@ -109,9 +139,19 @@ Content Page %d
 
        first.Paginator()
 
-       // Check paginator
-       assertFileContent(t, filepath.Join("public", "page", "3", "index.html"), false,
-               "Pag: Page 6",
-               "Pag: Page 7")
+       // Check Home paginator
+       assertFileContent(t, filepath.Join("public", "page", "2", "index.html"), false,
+               "Pag: Page 02")
+
+       // Check Sections
+       assertFileContent(t, filepath.Join("public", "sect1", "index.html"), false, "Section Title: Section", "Section1 <strong>Content!</strong>")
+       assertFileContent(t, filepath.Join("public", "sect2", "index.html"), false, "Section Title: Section", "Section2 <strong>Content!</strong>")
+
+       // Check Sections paginator
+       assertFileContent(t, filepath.Join("public", "sect1", "page", "2", "index.html"), false,
+               "Pag: Page 02")
+
+       sections := h.findPagesByNodeType(NodeSection)
+       require.Len(t, sections, 2)
 
 }
index 87f50fc912787a3a8c1bdd90966c37436bec17cb..60fddf55ccb338a024aec5062febc66ed00c6b12 100644 (file)
@@ -450,8 +450,12 @@ func (p *Page) layouts(l ...string) []string {
        }
 
        // TODO(bep) np
-       if p.NodeType == NodeHome {
+       switch p.NodeType {
+       case NodeHome:
                return []string{"index.html", "_default/list.html"}
+       case NodeSection:
+               section := p.Section()
+               return []string{"section/" + section + ".html", "_default/section.html", "_default/list.html", "indexes/" + section + ".html", "_default/indexes.html"}
        }
 
        if p.Layout != "" {
@@ -858,6 +862,15 @@ func (p *Page) update(f interface{}) error {
                }
        }
 
+       // TODO(bep) np node URL
+       // Set Node URL
+       switch p.NodeType {
+       case NodeHome:
+               p.URLPath.URL = ""
+       case NodeSection:
+               p.URLPath.URL = p.Section()
+       }
+
        return nil
 
 }
@@ -1133,10 +1146,15 @@ func (p *Page) FullFilePath() string {
 }
 
 func (p *Page) TargetPath() (outfile string) {
-       // TODO(bep) ml
-       if p.NodeType == NodeHome {
+
+       // TODO(bep) np
+       switch p.NodeType {
+       case NodeHome:
                return "index.html"
+       case NodeSection:
+               return filepath.Join(p.Section(), "index.html")
        }
+
        // Always use URL if it's specified
        if len(strings.TrimSpace(p.URLPath.URL)) > 2 {
                outfile = strings.TrimSpace(p.URLPath.URL)
@@ -1196,14 +1214,20 @@ func (p *Page) prepareLayouts() error {
        return nil
 }
 
-func (p *Page) prepareData() error {
+func (p *Page) prepareData(s *Site) error {
+       p.Data = make(map[string]interface{})
        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)
+               p.Data["Pages"] = s.owner.findPagesByNodeType(NodePage)
+       case NodeSection:
+               sectionData, ok := s.Sections[p.Section()]
+               if !ok {
+                       return fmt.Errorf("Data for section %s not found", p.Section())
+               }
+               p.Data["Pages"] = sectionData
        }
 
        return nil
@@ -1215,12 +1239,11 @@ 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)
-               }
+               // write alias for page 1
+               // TODO(bep) ml all of these n.addLang ... fix.
+               //permaLink, _ := p.Permalink()
+               // TODO(bep) np fix
+               //s.writeDestAlias(p.addLangPathPrefix(helpers.PaginateAliasPath("", 1)), permaLink, nil)
 
                pagers := p.paginator.Pagers()
 
@@ -1240,7 +1263,7 @@ func (p *Page) renderPaginator(s *Site) error {
                        }
 
                        pageNumber := i + 1
-                       htmlBase := fmt.Sprintf("/%s/%d", paginatePath, pageNumber)
+                       htmlBase := path.Join(p.URLPath.URL, fmt.Sprintf("/%s/%d", paginatePath, pageNumber))
                        htmlBase = p.addLangPathPrefix(htmlBase)
                        if err := s.renderAndWritePage(pagerNode.Title,
                                filepath.FromSlash(htmlBase), pagerNode, p.layouts()...); err != nil {
index c149ae13d203b1de92baeaa35873fd7809b7e96b..b2b7377b8c25a3399be7a23c8c802d50e2017229 100644 (file)
@@ -164,6 +164,7 @@ func pageToPermalinkFilename(p *Page, _ string) (string, error) {
 func pageToPermalinkSlugElseTitle(p *Page, a string) (string, error) {
        if p.Slug != "" {
                // Don't start or end with a -
+               // TODO(bep) this doesn't look good... Set the Slug once.
                if strings.HasPrefix(p.Slug, "-") {
                        p.Slug = p.Slug[1:len(p.Slug)]
                }
index 7d7ac438bb7f2b21c7259bbb895c2c91a7bfc86a..55bf1dc99c68a55fae4800c249797d617baf9e00 100644 (file)
@@ -1633,7 +1633,7 @@ func (s *Site) preparePages() error {
                if err := p.prepareLayouts(); err != nil {
                        errors = append(errors, err)
                }
-               if err := p.prepareData(); err != nil {
+               if err := p.prepareData(s); err != nil {
                        errors = append(errors, err)
                }
        }
@@ -1683,7 +1683,10 @@ 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 {
-               if err := s.renderAndWritePage("page "+p.FullFilePath(), p.TargetPath(), p, s.appendThemeTemplates(p.layouts())...); err != nil {
+               targetPath := p.TargetPath()
+               layouts := p.layouts()
+               jww.DEBUG.Printf("Render Page to %q with layouts %q", targetPath, layouts)
+               if err := s.renderAndWritePage("page "+p.FullFilePath(), targetPath, p, s.appendThemeTemplates(layouts)...); err != nil {
                        results <- err
                }
 
@@ -1962,6 +1965,9 @@ func (s *Site) newSectionListNode(prepare bool, sectionName, section string, dat
 
 // renderSectionLists renders a page for each section
 func (s *Site) renderSectionLists(prepare bool) error {
+       if nodePageFeatureFlag {
+               return nil
+       }
        for section, data := range s.Sections {
                // section keys can be lower case (depending on site.pathifyTaxonomyKeys)
                // extract the original casing from the first page to get sensible titles.