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-11-02 00:39:24 +0300
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2016-11-22 11:57:03 +0300
commit75c38071d8c61e2e1a56ae1949766b4144b68305 (patch)
tree4a73c2bffaafc7f151db5f6538e998fc7ddc184b /hugolib
parentf8bda16e154465c74a2cc42dd8149369e19f7833 (diff)
node to page: Create pages for nodes without content
Updates #2297
Diffstat (limited to 'hugolib')
-rw-r--r--hugolib/hugo_sites.go155
-rw-r--r--hugolib/node.go21
-rw-r--r--hugolib/node_as_page_test.go150
-rw-r--r--hugolib/page.go6
-rw-r--r--hugolib/site.go14
-rw-r--r--hugolib/site_render.go2
6 files changed, 297 insertions, 51 deletions
diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go
index 785fc847f..8332640df 100644
--- a/hugolib/hugo_sites.go
+++ b/hugolib/hugo_sites.go
@@ -25,6 +25,7 @@ import (
"github.com/spf13/viper"
+ "github.com/bep/inflect"
"github.com/fsnotify/fsnotify"
"github.com/spf13/hugo/source"
"github.com/spf13/hugo/tpl"
@@ -218,7 +219,7 @@ func (h *HugoSites) Build(config BuildCfg) error {
return err
}
- h.setupTranslations(firstSite)
+ h.setupTranslations()
if len(h.Sites) > 1 {
// Initialize the rest
@@ -236,6 +237,10 @@ func (h *HugoSites) Build(config BuildCfg) error {
}
}
+ if err := h.createMissingNodes(); err != nil {
+ return err
+ }
+
if err := h.preRender(config, whatChanged{source: true, other: true}); err != nil {
return err
}
@@ -299,7 +304,7 @@ func (h *HugoSites) Rebuild(config BuildCfg, events ...fsnotify.Event) error {
}
// Assign pages to sites per translation.
- h.setupTranslations(firstSite)
+ h.setupTranslations()
if changed.source {
h.assembleGitInfo()
@@ -310,6 +315,10 @@ func (h *HugoSites) Rebuild(config BuildCfg, events ...fsnotify.Event) error {
}
}
+ if err := h.createMissingNodes(); err != nil {
+ return err
+ }
+
if err := h.preRender(config, changed); err != nil {
return err
}
@@ -373,7 +382,147 @@ func (h *HugoSites) render() error {
return nil
}
-func (h *HugoSites) setupTranslations(master *Site) {
+// createMissingNodes creates home page, taxonomies etc. that isnt't created as an
+// effect of having a content file.
+func (h *HugoSites) createMissingNodes() error {
+ // TODO(bep) np revisit this on languages -- as this is currently run after the page language distribution (due to taxonomies)
+ // TODO(bep) np re above, Pages vs.
+ // TODO(bep) np check node title etc.
+ s := h.Sites[0]
+
+ home := s.findPagesByNodeType(NodeHome)
+
+ // home page
+ if len(home) == 0 {
+ s.Pages = append(s.Pages, s.newHomePage())
+ }
+
+ // taxonomy list and terms pages
+ taxonomies := s.Language.GetStringMapString("taxonomies")
+ if len(taxonomies) > 0 {
+ taxonomyPages := s.findPagesByNodeType(NodeTaxonomy)
+ taxonomyTermsPages := s.findPagesByNodeType(NodeTaxonomyTerms)
+ for _, plural := range taxonomies {
+ tax := s.Taxonomies[plural]
+ foundTaxonomyPage := false
+ foundTaxonomyTermsPage := false
+ for key, _ := range tax {
+ for _, p := range taxonomyPages {
+ if p.sections[0] == plural && p.sections[1] == key {
+ foundTaxonomyPage = true
+ break
+ }
+ }
+ for _, p := range taxonomyTermsPages {
+ if p.sections[0] == plural {
+ foundTaxonomyTermsPage = true
+ break
+ }
+ }
+ if !foundTaxonomyPage {
+ s.Pages = append(s.Pages, s.newTaxonomyPage(plural, key))
+ }
+
+ if !foundTaxonomyTermsPage {
+ s.Pages = append(s.Pages, s.newTaxonomyTermsPage(plural))
+ }
+ }
+
+ }
+ }
+
+ // sections
+ sectionPages := s.findPagesByNodeType(NodeSection)
+ if len(sectionPages) < len(s.Sections) {
+ for name, section := range s.Sections {
+ foundSection := false
+ for _, sectionPage := range sectionPages {
+ if sectionPage.sections[0] == name {
+ foundSection = true
+ break
+ }
+ }
+ if !foundSection {
+ s.Pages = append(s.Pages, s.newSectionPage(name, section))
+ }
+ }
+ }
+
+ return nil
+}
+
+// Move the new* methods after cleanup in site.go
+func (s *Site) newNodePage(typ NodeType) *Page {
+ n := Node{
+ NodeType: typ,
+ Data: make(map[string]interface{}),
+ Site: &s.Info,
+ language: s.Language,
+ }
+
+ return &Page{Node: n}
+}
+
+func (s *Site) newHomePage() *Page {
+ p := s.newNodePage(NodeHome)
+ p.Title = s.Info.Title
+ // TODO(bep) np check Data pages
+ // TODO(bep) np check setURLs
+ return p
+}
+
+func (s *Site) newTaxonomyPage(plural, key string) *Page {
+
+ p := s.newNodePage(NodeTaxonomy)
+
+ p.sections = []string{plural, key}
+
+ if s.Info.preserveTaxonomyNames {
+ key = s.Info.pathSpec.MakePathSanitized(key)
+ }
+
+ if s.Info.preserveTaxonomyNames {
+ // keep as is in the title
+ p.Title = key
+ } else {
+ p.Title = strings.Replace(strings.Title(key), "-", " ", -1)
+ }
+
+ // TODO(bep) np check set url
+
+ return p
+}
+
+func (s *Site) newSectionPage(name string, section WeightedPages) *Page {
+
+ p := s.newNodePage(NodeSection)
+ p.sections = []string{name}
+
+ sectionName := name
+ if !s.Info.preserveTaxonomyNames && len(section) > 0 {
+ sectionName = section[0].Page.Section()
+ }
+
+ sectionName = helpers.FirstUpper(sectionName)
+ if viper.GetBool("pluralizeListTitles") {
+ p.Title = inflect.Pluralize(sectionName)
+ } else {
+ p.Title = sectionName
+ }
+
+ return p
+}
+
+func (s *Site) newTaxonomyTermsPage(plural string) *Page {
+ p := s.newNodePage(NodeTaxonomyTerms)
+ p.sections = []string{plural}
+ p.Title = strings.Title(plural)
+ return p
+}
+
+func (h *HugoSites) setupTranslations() {
+
+ master := h.Sites[0]
for _, p := range master.rawAllPages {
if p.Lang() == "" {
diff --git a/hugolib/node.go b/hugolib/node.go
index 13e124608..f01b4c822 100644
--- a/hugolib/node.go
+++ b/hugolib/node.go
@@ -43,6 +43,25 @@ const (
NodeTaxonomyTerms
)
+func (p NodeType) String() string {
+ switch p {
+ case NodePage:
+ return "page"
+ case NodeHome:
+ return "home page"
+ case NodeSection:
+ return "section list"
+ case NodeTaxonomy:
+ return "taxonomy list"
+ case NodeTaxonomyTerms:
+ return "taxonomy terms"
+ case NodeUnknown:
+ return "unknown"
+ default:
+ return "invalid value"
+ }
+}
+
func (p NodeType) IsNode() bool {
return p >= NodeHome
}
@@ -384,7 +403,7 @@ func (p *Page) setNodeTypeVars(s *Site) {
case NodeHome:
p.URLPath.URL = ""
case NodeSection:
- p.URLPath.URL = p.Section()
+ p.URLPath.URL = p.sections[0]
case NodeTaxonomy:
p.URLPath.URL = path.Join(p.sections...)
case NodeTaxonomyTerms:
diff --git a/hugolib/node_as_page_test.go b/hugolib/node_as_page_test.go
index 090323cec..9c8506503 100644
--- a/hugolib/node_as_page_test.go
+++ b/hugolib/node_as_page_test.go
@@ -49,6 +49,8 @@ func TestNodesAsPage(t *testing.T) {
testCommonResetState()
+ writeLayoutsForNodeAsPageTests(t)
+
writeSource(t, filepath.Join("content", "_node.md"), `---
title: Home Sweet Home!
---
@@ -85,48 +87,6 @@ title: Taxonomy Term Categories
Taxonomy Term Categories **Content!**
`)
- writeSource(t, filepath.Join("layouts", "index.html"), `
-Index Title: {{ .Title }}
-Index Content: {{ .Content }}
-# Pages: {{ len .Data.Pages }}
-{{ range .Paginator.Pages }}
- Pag: {{ .Title }}
-{{ end }}
-`)
-
- 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 }}
-`)
-
- // Taxonomy lists
- writeSource(t, filepath.Join("layouts", "_default", "taxonomy.html"), `
-Taxonomy Title: {{ .Title }}
-Taxonomy Content: {{ .Content }}
-# Pages: {{ len .Data.Pages }}
-{{ range .Paginator.Pages }}
- Pag: {{ .Title }}
-{{ end }}
-`)
-
- // Taxonomy terms
- writeSource(t, filepath.Join("layouts", "_default", "terms.html"), `
-Taxonomy Terms Title: {{ .Title }}
-Taxonomy Terms Content: {{ .Content }}
-{{ range $key, $value := .Data.Terms }}
- k/v: {{ $key }} / {{ printf "%=v" $value }}
-{{ end }}
-`)
-
// Add some regular pages
for i := 1; i <= 4; i++ {
sect := "sect1"
@@ -213,3 +173,109 @@ Content Page %02d
// There are no pages to paginate over in the taxonomy terms.
}
+
+func TestNodesWithNoContentFile(t *testing.T) {
+ //jww.SetStdoutThreshold(jww.LevelDebug)
+ jww.SetStdoutThreshold(jww.LevelFatal)
+
+ nodePageFeatureFlag = true
+ defer toggleNodePageFeatureFlag()
+
+ testCommonResetState()
+
+ writeLayoutsForNodeAsPageTests(t)
+
+ 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",
+ "Web"
+]
+---
+Content Page %02d
+`, i, i))
+ }
+
+ viper.Set("paginate", 1)
+ viper.Set("title", "Hugo Rocks!")
+
+ s := newSiteDefaultLang()
+
+ if err := buildAndRenderSite(s); err != nil {
+ t.Fatalf("Failed to build site: %s", err)
+ }
+
+ // Home page
+ homePages := s.findPagesByNodeType(NodeHome)
+ require.Len(t, homePages, 1)
+
+ homePage := homePages[0]
+ require.Len(t, homePage.Data["Pages"], 4)
+
+ assertFileContent(t, filepath.Join("public", "index.html"), false,
+ "Index Title: Hugo Rocks!")
+
+ // Taxonomy list
+ assertFileContent(t, filepath.Join("public", "categories", "hugo", "index.html"), false,
+ "Taxonomy Title: Hugo")
+
+ // Taxonomy terms
+ assertFileContent(t, filepath.Join("public", "categories", "index.html"), false,
+ "Taxonomy Terms Title: Categories")
+
+ // Sections
+ assertFileContent(t, filepath.Join("public", "sect1", "index.html"), false,
+ "Section Title: Sect1s")
+ assertFileContent(t, filepath.Join("public", "sect2", "index.html"), false,
+ "Section Title: Sect2s")
+
+}
+
+func writeLayoutsForNodeAsPageTests(t *testing.T) {
+ writeSource(t, filepath.Join("layouts", "index.html"), `
+Index Title: {{ .Title }}
+Index Content: {{ .Content }}
+# Pages: {{ len .Data.Pages }}
+{{ range .Paginator.Pages }}
+ Pag: {{ .Title }}
+{{ end }}
+`)
+
+ 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 }}
+`)
+
+ // Taxonomy lists
+ writeSource(t, filepath.Join("layouts", "_default", "taxonomy.html"), `
+Taxonomy Title: {{ .Title }}
+Taxonomy Content: {{ .Content }}
+# Pages: {{ len .Data.Pages }}
+{{ range .Paginator.Pages }}
+ Pag: {{ .Title }}
+{{ end }}
+`)
+
+ // Taxonomy terms
+ writeSource(t, filepath.Join("layouts", "_default", "terms.html"), `
+Taxonomy Terms Title: {{ .Title }}
+Taxonomy Terms Content: {{ .Content }}
+{{ range $key, $value := .Data.Terms }}
+ k/v: {{ $key }} / {{ printf "%=v" $value }}
+{{ end }}
+`)
+}
diff --git a/hugolib/page.go b/hugolib/page.go
index c8ce5ca4a..ec728d4c8 100644
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -470,7 +470,7 @@ func (p *Page) layouts(l ...string) []string {
case NodeHome:
return []string{"index.html", "_default/list.html"}
case NodeSection:
- section := p.Section()
+ section := p.sections[0]
return []string{"section/" + section + ".html", "_default/section.html", "_default/list.html", "indexes/" + section + ".html", "_default/indexes.html"}
case NodeTaxonomy:
singular := p.site.taxonomiesPluralSingular[p.sections[0]]
@@ -1167,7 +1167,7 @@ func (p *Page) TargetPath() (outfile string) {
case NodeHome:
return "index.html"
case NodeSection:
- return filepath.Join(p.Section(), "index.html")
+ return filepath.Join(p.sections[0], "index.html")
case NodeTaxonomy:
return filepath.Join(append(p.sections, "index.html")...)
case NodeTaxonomyTerms:
@@ -1242,7 +1242,7 @@ func (p *Page) prepareData(s *Site) error {
// TODO(bep) np cache the below
p.Data["Pages"] = s.owner.findAllPagesByNodeType(NodePage)
case NodeSection:
- sectionData, ok := s.Sections[p.Section()]
+ sectionData, ok := s.Sections[p.sections[0]]
if !ok {
return fmt.Errorf("Data for section %s not found", p.Section())
}
diff --git a/hugolib/site.go b/hugolib/site.go
index 8eef37b0b..6de1daaa9 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -1606,8 +1606,12 @@ func (s *Site) nodeTypeFromSections(sections []string) NodeType {
}
func (s *Site) findPagesByNodeType(n NodeType) Pages {
+ return s.findPagesByNodeTypeIn(n, s.Pages)
+}
+
+func (s *Site) findPagesByNodeTypeIn(n NodeType, inPages Pages) Pages {
var pages Pages
- for _, p := range s.Pages {
+ for _, p := range inPages {
if p.NodeType == n {
pages = append(pages, p)
}
@@ -1615,6 +1619,14 @@ func (s *Site) findPagesByNodeType(n NodeType) Pages {
return pages
}
+func (s *Site) findAllPagesByNodeType(n NodeType) Pages {
+ return s.findPagesByNodeTypeIn(n, s.rawAllPages)
+}
+
+func (s *Site) findRawAllPagesByNodeType(n NodeType) Pages {
+ return s.findPagesByNodeTypeIn(n, s.rawAllPages)
+}
+
// renderAliases renders shell pages that simply have a redirect in the header.
func (s *Site) renderAliases() error {
for _, p := range s.Pages {
diff --git a/hugolib/site_render.go b/hugolib/site_render.go
index c91a78413..bad831d6c 100644
--- a/hugolib/site_render.go
+++ b/hugolib/site_render.go
@@ -65,7 +65,7 @@ func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.Wa
for p := range pages {
targetPath := p.TargetPath()
layouts := p.layouts()
- jww.DEBUG.Printf("Render Page to %q with layouts %q", targetPath, layouts)
+ jww.DEBUG.Printf("Render %s to %q with layouts %q", p.NodeType, targetPath, layouts)
if err := s.renderAndWritePage("page "+p.FullFilePath(), targetPath, p, s.appendThemeTemplates(layouts)...); err != nil {
results <- err
}