ref: 3ff25b37a3d327646255572072d6686d48a142e9
parent: 75c38071d8c61e2e1a56ae1949766b4144b68305
author: Bjørn Erik Pedersen <[email protected]>
date: Wed Nov 2 17:34:19 EDT 2016
node to page: Handle RSS Updates #2297
--- a/hugolib/hugo_sites.go
+++ b/hugolib/hugo_sites.go
@@ -17,6 +17,7 @@
"errors"
"fmt"
"os"
+ "path"
"strings"
"sync"
"time"
@@ -390,6 +391,11 @@
// TODO(bep) np check node title etc.
s := h.Sites[0]
+ // TODO(bep) np
+ for _, p := range s.Pages {
+ p.setNodeTypeVars(s)
+ }
+
home := s.findPagesByNodeType(NodeHome)
// home page
@@ -460,7 +466,7 @@
language: s.Language,
}
- return &Page{Node: n}
+ return &Page{Node: n, site: s}
}
func (s *Site) newHomePage() *Page {
@@ -489,6 +495,7 @@
}
// TODO(bep) np check set url
+ p.URLPath.URL = path.Join(plural, key)
return p
}
@@ -509,7 +516,7 @@
} else {
p.Title = sectionName
}
-
+ p.URLPath.URL = name
return p
}
@@ -612,8 +619,6 @@
// No need to process it again.
continue
}
-
- p.setNodeTypeVars(s)
// If we got this far it means that this is either a new Page pointer
// or a template or similar has changed so wee need to do a rerendering
--- a/hugolib/node_as_page_test.go
+++ b/hugolib/node_as_page_test.go
@@ -31,8 +31,8 @@
*/
func TestNodesAsPage(t *testing.T) {
- //jww.SetStdoutThreshold(jww.LevelDebug)
- jww.SetStdoutThreshold(jww.LevelFatal)
+ jww.SetStdoutThreshold(jww.LevelDebug)
+ //jww.SetStdoutThreshold(jww.LevelFatal)
nodePageFeatureFlag = true
defer toggleNodePageFeatureFlag()
@@ -105,6 +105,8 @@
}
viper.Set("paginate", 1)
+ viper.Set("title", "Hugo Rocks")
+ viper.Set("rssURI", "customrss.xml")
s := newSiteDefaultLang()
@@ -172,11 +174,18 @@
// There are no pages to paginate over in the taxonomy terms.
+ // RSS
+ assertFileContent(t, filepath.Join("public", "customrss.xml"), false, "Recent content in Home Sweet Home! on Hugo Rocks", "<rss")
+ assertFileContent(t, filepath.Join("public", "sect1", "customrss.xml"), false, "Recent content in Section1 on Hugo Rocks", "<rss")
+ assertFileContent(t, filepath.Join("public", "sect2", "customrss.xml"), false, "Recent content in Section2 on Hugo Rocks", "<rss")
+ assertFileContent(t, filepath.Join("public", "categories", "hugo", "customrss.xml"), false, "Recent content in Taxonomy Hugo on Hugo Rocks", "<rss")
+ assertFileContent(t, filepath.Join("public", "categories", "web", "customrss.xml"), false, "Recent content in Taxonomy Web on Hugo Rocks", "<rss")
+
}
func TestNodesWithNoContentFile(t *testing.T) {
- //jww.SetStdoutThreshold(jww.LevelDebug)
- jww.SetStdoutThreshold(jww.LevelFatal)
+ jww.SetStdoutThreshold(jww.LevelDebug)
+ //jww.SetStdoutThreshold(jww.LevelFatal)
nodePageFeatureFlag = true
defer toggleNodePageFeatureFlag()
@@ -203,6 +212,7 @@
viper.Set("paginate", 1)
viper.Set("title", "Hugo Rocks!")
+ viper.Set("rssURI", "customrss.xml")
s := newSiteDefaultLang()
@@ -233,6 +243,13 @@
"Section Title: Sect1s")
assertFileContent(t, filepath.Join("public", "sect2", "index.html"), false,
"Section Title: Sect2s")
+
+ // RSS
+ assertFileContent(t, filepath.Join("public", "customrss.xml"), false, "Recent content in Hugo Rocks! on Hugo Rocks!", "<rss")
+ assertFileContent(t, filepath.Join("public", "sect1", "customrss.xml"), false, "Recent content in Sect1s on Hugo Rocks!", "<rss")
+ assertFileContent(t, filepath.Join("public", "sect2", "customrss.xml"), false, "Recent content in Sect2s on Hugo Rocks!", "<rss")
+ assertFileContent(t, filepath.Join("public", "categories", "hugo", "customrss.xml"), false, "Recent content in Hugo on Hugo Rocks!", "<rss")
+ assertFileContent(t, filepath.Join("public", "categories", "web", "customrss.xml"), false, "Recent content in Web on Hugo Rocks!", "<rss")
}
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -95,6 +95,8 @@
PageMeta
Source
Position `json:"-"`
+
+ // TODO(bep) np pointer, or remove
Node
GitInfo *gitmap.GitInfo
@@ -496,6 +498,29 @@
return layouts(p.Type(), layout)
}
+// TODO(bep) np consolidate and test these NodeType switches
+// rssLayouts returns RSS layouts to use for the RSS version of this page, nil
+// if no RSS should be rendered.
+func (p *Page) rssLayouts() []string {
+ switch p.NodeType {
+ case NodeHome:
+ return []string{"rss.xml", "_default/rss.xml", "_internal/_default/rss.xml"}
+ case NodeSection:
+ section := p.sections[0]
+ return []string{"section/" + section + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
+ case NodeTaxonomy:
+ singular := p.site.taxonomiesPluralSingular[p.sections[0]]
+ return []string{"taxonomy/" + singular + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
+ case NodeTaxonomyTerms:
+ // No RSS for taxonomy terms
+ case NodePage:
+ // No RSS for regular pages
+ }
+
+ return nil
+
+}
+
func layouts(types string, layout string) (layouts []string) {
t := strings.Split(types, "/")
@@ -1246,7 +1271,7 @@
if !ok {
return fmt.Errorf("Data for section %s not found", p.Section())
}
- p.Data["Pages"] = sectionData
+ p.Data["Pages"] = sectionData.Pages()
case NodeTaxonomy:
plural := p.sections[0]
term := p.sections[1]
@@ -1278,7 +1303,7 @@
// 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 := &Page{Node: Node{NodeType: p.NodeType, Site: p.Site}}
c.Title = p.Title
c.Data = p.Data
c.Date = p.Date
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -2322,6 +2322,7 @@
}
func (s *Site) renderAndWriteXML(name string, dest string, d interface{}, layouts ...string) error {
+ jww.DEBUG.Printf("Render XML for %q to %q", name, dest)
renderBuffer := bp.GetBuffer()
defer bp.PutBuffer(renderBuffer)
renderBuffer.WriteString("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>\n")
--- a/hugolib/site_render.go
+++ b/hugolib/site_render.go
@@ -76,6 +76,10 @@
results <- err
}
}
+
+ if err := s.renderRSS(p); err != nil {
+ results <- err
+ }
}
}
@@ -119,5 +123,27 @@
}
}
+ return nil
+}
+
+func (s *Site) renderRSS(p *Page) error {
+ layouts := p.rssLayouts()
+
+ if layouts == nil {
+ // No RSS for this NodeType
+ return nil
+ }
+
+ // TODO(bep) np check RSS titles
+ rssNode := p.copy()
+
+ // TODO(bep) np todelido URL
+ rssURI := s.Language.GetString("rssURI")
+ rssNode.URLPath.URL = path.Join(rssNode.URLPath.URL, rssURI)
+
+ if err := s.renderAndWriteXML(rssNode.Title, rssNode.URLPath.URL, rssNode, s.appendThemeTemplates(layouts)...); err != nil {
+ return err
+ }
+
return nil
}