mirror of
https://github.com/gohugoio/hugo.git
synced 2025-03-20 00:03:06 +00:00
parent
c2f3cb2d7a
commit
3737c9bcb3
6 changed files with 271 additions and 124 deletions
|
@ -464,6 +464,8 @@ func (s *Site) preparePagesForRender(cfg BuildCfg, changed whatChanged) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.setNodeTypeVars(s)
|
||||||
|
|
||||||
// If we got this far it means that this is either a new Page pointer
|
// 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
|
// or a template or similar has changed so wee need to do a rerendering
|
||||||
// of the shortcodes etc.
|
// of the shortcodes etc.
|
||||||
|
@ -572,7 +574,7 @@ func (s *Site) updateBuildStats(page *Page) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HugoSites) findPagesByNodeType(n NodeType) Pages {
|
func (h *HugoSites) findAllPagesByNodeType(n NodeType) Pages {
|
||||||
var pages Pages
|
var pages Pages
|
||||||
for _, p := range h.Sites[0].AllPages {
|
for _, p := range h.Sites[0].AllPages {
|
||||||
if p.NodeType == n {
|
if p.NodeType == n {
|
||||||
|
|
|
@ -32,9 +32,13 @@ type NodeType int
|
||||||
const (
|
const (
|
||||||
NodePage NodeType = iota
|
NodePage NodeType = iota
|
||||||
|
|
||||||
|
// Temporary state.
|
||||||
|
NodeUnknown
|
||||||
|
|
||||||
// The rest are node types; home page, sections etc.
|
// The rest are node types; home page, sections etc.
|
||||||
NodeHome
|
NodeHome
|
||||||
NodeSection
|
NodeSection
|
||||||
|
NodeTaxonomy
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p NodeType) IsNode() bool {
|
func (p NodeType) IsNode() bool {
|
||||||
|
@ -337,8 +341,14 @@ func (n *Node) addLangFilepathPrefix(outfile string) string {
|
||||||
return helpers.FilePathSeparator + filepath.Join(n.Lang(), outfile)
|
return helpers.FilePathSeparator + filepath.Join(n.Lang(), outfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sectionsFromFilename(filename string) []string {
|
||||||
|
dir, _ := filepath.Split(filename)
|
||||||
|
return strings.Split(dir, helpers.FilePathSeparator)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(bep) np node identificator
|
||||||
func nodeTypeFromFilename(filename string) NodeType {
|
func nodeTypeFromFilename(filename string) NodeType {
|
||||||
// TODO(bep) np
|
|
||||||
if !strings.Contains(filename, "_node") {
|
if !strings.Contains(filename, "_node") {
|
||||||
return NodePage
|
return NodePage
|
||||||
}
|
}
|
||||||
|
@ -347,5 +357,32 @@ func nodeTypeFromFilename(filename string) NodeType {
|
||||||
return NodeHome
|
return NodeHome
|
||||||
}
|
}
|
||||||
|
|
||||||
return NodeSection
|
// We don't know enough yet to determine the type.
|
||||||
|
return NodeUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Page) setNodeTypeVars(s *Site) {
|
||||||
|
// TODO(bep) np taxonomies etc.
|
||||||
|
if p.NodeType == NodeUnknown {
|
||||||
|
// This is either a taxonomy or a section
|
||||||
|
if s.isTaxonomy(p.Section()) {
|
||||||
|
p.NodeType = NodeTaxonomy
|
||||||
|
} else {
|
||||||
|
p.NodeType = NodeSection
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// TODO(bep) np node URL
|
||||||
|
// Set Node URL
|
||||||
|
switch p.NodeType {
|
||||||
|
case NodeHome:
|
||||||
|
p.URLPath.URL = ""
|
||||||
|
case NodeSection:
|
||||||
|
p.URLPath.URL = p.Section()
|
||||||
|
case NodeTaxonomy:
|
||||||
|
p.URLPath.URL = path.Join(p.sections...)
|
||||||
|
}
|
||||||
|
|
||||||
|
p.site = s
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,8 @@ import (
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func TestNodesAsPage(t *testing.T) {
|
func TestNodesAsPage(t *testing.T) {
|
||||||
//jww.SetStdoutThreshold(jww.LevelDebug)
|
jww.SetStdoutThreshold(jww.LevelDebug)
|
||||||
jww.SetStdoutThreshold(jww.LevelFatal)
|
//jww.SetStdoutThreshold(jww.LevelFatal)
|
||||||
|
|
||||||
nodePageFeatureFlag = true
|
nodePageFeatureFlag = true
|
||||||
defer toggleNodePageFeatureFlag()
|
defer toggleNodePageFeatureFlag()
|
||||||
|
@ -65,6 +65,12 @@ Section1 **Content!**
|
||||||
title: Section2
|
title: Section2
|
||||||
---
|
---
|
||||||
Section2 **Content!**
|
Section2 **Content!**
|
||||||
|
`)
|
||||||
|
|
||||||
|
writeSource(t, filepath.Join("content", "categories", "hugo", "_node.md"), `---
|
||||||
|
title: Taxonomy Hugo
|
||||||
|
---
|
||||||
|
Taxonomy Hugo **Content!**
|
||||||
`)
|
`)
|
||||||
|
|
||||||
writeSource(t, filepath.Join("layouts", "index.html"), `
|
writeSource(t, filepath.Join("layouts", "index.html"), `
|
||||||
|
@ -88,6 +94,15 @@ Section Content: {{ .Content }}
|
||||||
{{ range .Paginator.Pages }}
|
{{ range .Paginator.Pages }}
|
||||||
Pag: {{ .Title }}
|
Pag: {{ .Title }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
`)
|
||||||
|
|
||||||
|
writeSource(t, filepath.Join("layouts", "_default", "taxonomy.html"), `
|
||||||
|
Taxonomy Title: {{ .Title }}
|
||||||
|
Taxonomy Content: {{ .Content }}
|
||||||
|
# Pages: {{ len .Data.Pages }}
|
||||||
|
{{ range .Paginator.Pages }}
|
||||||
|
Pag: {{ .Title }}
|
||||||
|
{{ end }}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
// Add some regular pages
|
// Add some regular pages
|
||||||
|
@ -120,7 +135,7 @@ Content Page %02d
|
||||||
assertFileContent(t, filepath.Join("public", "sect1", "regular1", "index.html"), false, "Single Title: Page 01", "Content Page 01")
|
assertFileContent(t, filepath.Join("public", "sect1", "regular1", "index.html"), false, "Single Title: Page 01", "Content Page 01")
|
||||||
|
|
||||||
h := s.owner
|
h := s.owner
|
||||||
nodes := h.findPagesByNodeType(NodeHome)
|
nodes := h.findAllPagesByNodeType(NodeHome)
|
||||||
require.Len(t, nodes, 1)
|
require.Len(t, nodes, 1)
|
||||||
|
|
||||||
home := nodes[0]
|
home := nodes[0]
|
||||||
|
@ -129,7 +144,7 @@ Content Page %02d
|
||||||
require.True(t, home.IsNode())
|
require.True(t, home.IsNode())
|
||||||
require.False(t, home.IsPage())
|
require.False(t, home.IsPage())
|
||||||
|
|
||||||
pages := h.findPagesByNodeType(NodePage)
|
pages := h.findAllPagesByNodeType(NodePage)
|
||||||
require.Len(t, pages, 4)
|
require.Len(t, pages, 4)
|
||||||
|
|
||||||
first := pages[0]
|
first := pages[0]
|
||||||
|
@ -151,7 +166,16 @@ Content Page %02d
|
||||||
assertFileContent(t, filepath.Join("public", "sect1", "page", "2", "index.html"), false,
|
assertFileContent(t, filepath.Join("public", "sect1", "page", "2", "index.html"), false,
|
||||||
"Pag: Page 02")
|
"Pag: Page 02")
|
||||||
|
|
||||||
sections := h.findPagesByNodeType(NodeSection)
|
sections := h.findAllPagesByNodeType(NodeSection)
|
||||||
require.Len(t, sections, 2)
|
require.Len(t, sections, 2)
|
||||||
|
|
||||||
|
// Check taxonomy list
|
||||||
|
assertFileContent(t, filepath.Join("public", "categories", "hugo", "index.html"), false,
|
||||||
|
"Taxonomy Title: Taxonomy Hugo", "Taxonomy Hugo <strong>Content!</strong>")
|
||||||
|
|
||||||
|
// Check taxonomy list paginator
|
||||||
|
assertFileContent(t, filepath.Join("public", "categories", "hugo", "page", "2", "index.html"), false,
|
||||||
|
"Taxonomy Title: Taxonomy Hugo",
|
||||||
|
"Pag: Page 02")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,21 @@ type Page struct {
|
||||||
Node
|
Node
|
||||||
|
|
||||||
GitInfo *gitmap.GitInfo
|
GitInfo *gitmap.GitInfo
|
||||||
|
|
||||||
|
// This was added as part of getting the Nodes (taxonomies etc.) to work as
|
||||||
|
// Pages in Hugo 0.18.
|
||||||
|
// It is deliberately named similar to Section, but not exported (for now).
|
||||||
|
// We currently have only one level of section in Hugo, but the page can live
|
||||||
|
// any number of levels down the file path.
|
||||||
|
// To support taxonomies like /categories/hugo etc. we will need to keep track
|
||||||
|
// of that information in a general way.
|
||||||
|
// So, sections represents the path to the content, i.e. a content file or a
|
||||||
|
// virtual content file in the situations where a taxonomy or a section etc.
|
||||||
|
// isn't accomanied by one.
|
||||||
|
sections []string
|
||||||
|
|
||||||
|
// TODO(bep) np Site added to page, keep?
|
||||||
|
site *Site
|
||||||
}
|
}
|
||||||
|
|
||||||
type Source struct {
|
type Source struct {
|
||||||
|
@ -418,6 +433,7 @@ func newPage(filename string) *Page {
|
||||||
Node: Node{NodeType: nodeTypeFromFilename(filename), Keywords: []string{}, Sitemap: Sitemap{Priority: -1}},
|
Node: Node{NodeType: nodeTypeFromFilename(filename), Keywords: []string{}, Sitemap: Sitemap{Priority: -1}},
|
||||||
Params: make(map[string]interface{}),
|
Params: make(map[string]interface{}),
|
||||||
translations: make(Pages, 0),
|
translations: make(Pages, 0),
|
||||||
|
sections: sectionsFromFilename(filename),
|
||||||
}
|
}
|
||||||
|
|
||||||
jww.DEBUG.Println("Reading from", page.File.Path())
|
jww.DEBUG.Println("Reading from", page.File.Path())
|
||||||
|
@ -449,15 +465,20 @@ func (p *Page) layouts(l ...string) []string {
|
||||||
return p.layoutsCalculated
|
return p.layoutsCalculated
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bep) np
|
// TODO(bep) np taxonomy etc.
|
||||||
switch p.NodeType {
|
switch p.NodeType {
|
||||||
case NodeHome:
|
case NodeHome:
|
||||||
return []string{"index.html", "_default/list.html"}
|
return []string{"index.html", "_default/list.html"}
|
||||||
case NodeSection:
|
case NodeSection:
|
||||||
section := p.Section()
|
section := p.Section()
|
||||||
return []string{"section/" + section + ".html", "_default/section.html", "_default/list.html", "indexes/" + section + ".html", "_default/indexes.html"}
|
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]]
|
||||||
|
return []string{"taxonomy/" + singular + ".html", "indexes/" + singular + ".html", "_default/taxonomy.html", "_default/list.html"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Regular Page handled below
|
||||||
|
|
||||||
if p.Layout != "" {
|
if p.Layout != "" {
|
||||||
return layouts(p.Type(), p.Layout)
|
return layouts(p.Type(), p.Layout)
|
||||||
}
|
}
|
||||||
|
@ -862,15 +883,6 @@ 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
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1153,6 +1165,8 @@ func (p *Page) TargetPath() (outfile string) {
|
||||||
return "index.html"
|
return "index.html"
|
||||||
case NodeSection:
|
case NodeSection:
|
||||||
return filepath.Join(p.Section(), "index.html")
|
return filepath.Join(p.Section(), "index.html")
|
||||||
|
case NodeTaxonomy:
|
||||||
|
return filepath.Join(append(p.sections, "index.html")...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always use URL if it's specified
|
// Always use URL if it's specified
|
||||||
|
@ -1214,67 +1228,37 @@ func (p *Page) prepareLayouts() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(bep) np naming, move some
|
||||||
func (p *Page) prepareData(s *Site) error {
|
func (p *Page) prepareData(s *Site) error {
|
||||||
p.Data = make(map[string]interface{})
|
p.Data = make(map[string]interface{})
|
||||||
switch p.NodeType {
|
switch p.NodeType {
|
||||||
case NodePage:
|
case NodePage:
|
||||||
case NodeHome:
|
case NodeHome:
|
||||||
// TODO(bep) np cache the below
|
// TODO(bep) np cache the below
|
||||||
// TODO(bep) np
|
p.Data["Pages"] = s.owner.findAllPagesByNodeType(NodePage)
|
||||||
p.Data["Pages"] = s.owner.findPagesByNodeType(NodePage)
|
|
||||||
case NodeSection:
|
case NodeSection:
|
||||||
sectionData, ok := s.Sections[p.Section()]
|
sectionData, ok := s.Sections[p.Section()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Data for section %s not found", p.Section())
|
return fmt.Errorf("Data for section %s not found", p.Section())
|
||||||
}
|
}
|
||||||
p.Data["Pages"] = sectionData
|
p.Data["Pages"] = sectionData
|
||||||
|
case NodeTaxonomy:
|
||||||
|
plural := p.sections[0]
|
||||||
|
term := p.sections[1]
|
||||||
|
|
||||||
|
singular := s.taxonomiesPluralSingular[plural]
|
||||||
|
taxonomy := s.Taxonomies[plural].Get(term)
|
||||||
|
|
||||||
|
p.Data[singular] = taxonomy
|
||||||
|
p.Data["Singular"] = singular
|
||||||
|
p.Data["Plural"] = plural
|
||||||
|
p.Data["Pages"] = taxonomy.Pages()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
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()
|
|
||||||
// TODO(bep) np fix
|
|
||||||
//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 := 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 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Page constains some sync.Once which have a mutex, so we cannot just
|
// 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,
|
// copy the Page by value. So for the situations where we need a copy,
|
||||||
// the paginators etc., we do it manually here.
|
// the paginators etc., we do it manually here.
|
||||||
|
|
102
hugolib/site.go
102
hugolib/site.go
|
@ -91,11 +91,16 @@ type Site struct {
|
||||||
nodeCache *nodeCache
|
nodeCache *nodeCache
|
||||||
nodeCacheInit sync.Once
|
nodeCacheInit sync.Once
|
||||||
|
|
||||||
Pages Pages
|
Pages Pages
|
||||||
AllPages Pages
|
AllPages Pages
|
||||||
rawAllPages Pages
|
rawAllPages Pages
|
||||||
Files []*source.File
|
Files []*source.File
|
||||||
Taxonomies TaxonomyList
|
Taxonomies TaxonomyList
|
||||||
|
|
||||||
|
// Plural is what we get in the folder, so keep track of this mapping
|
||||||
|
// to get the singular form from that value.
|
||||||
|
taxonomiesPluralSingular map[string]string
|
||||||
|
|
||||||
Source source.Input
|
Source source.Input
|
||||||
Sections Taxonomy
|
Sections Taxonomy
|
||||||
Info SiteInfo
|
Info SiteInfo
|
||||||
|
@ -1514,12 +1519,14 @@ func (s *Site) assembleMenus() {
|
||||||
|
|
||||||
func (s *Site) assembleTaxonomies() {
|
func (s *Site) assembleTaxonomies() {
|
||||||
s.Taxonomies = make(TaxonomyList)
|
s.Taxonomies = make(TaxonomyList)
|
||||||
|
s.taxonomiesPluralSingular = make(map[string]string)
|
||||||
|
|
||||||
taxonomies := s.Language.GetStringMapString("Taxonomies")
|
taxonomies := s.Language.GetStringMapString("Taxonomies")
|
||||||
jww.INFO.Printf("found taxonomies: %#v\n", taxonomies)
|
jww.INFO.Printf("found taxonomies: %#v\n", taxonomies)
|
||||||
|
|
||||||
for _, plural := range taxonomies {
|
for singular, plural := range taxonomies {
|
||||||
s.Taxonomies[plural] = make(Taxonomy)
|
s.Taxonomies[plural] = make(Taxonomy)
|
||||||
|
s.taxonomiesPluralSingular[plural] = singular
|
||||||
for _, p := range s.Pages {
|
for _, p := range s.Pages {
|
||||||
vals := p.getParam(plural, !s.Info.preserveTaxonomyNames)
|
vals := p.getParam(plural, !s.Info.preserveTaxonomyNames)
|
||||||
weight := p.GetParam(plural + "_weight")
|
weight := p.GetParam(plural + "_weight")
|
||||||
|
@ -1569,9 +1576,13 @@ func (s *Site) resetBuildState() {
|
||||||
func (s *Site) assembleSections() {
|
func (s *Site) assembleSections() {
|
||||||
s.Sections = make(Taxonomy)
|
s.Sections = make(Taxonomy)
|
||||||
s.Info.Sections = s.Sections
|
s.Info.Sections = s.Sections
|
||||||
|
regularPages := s.findPagesByNodeType(NodePage)
|
||||||
for i, p := range s.Pages {
|
for i, p := range regularPages {
|
||||||
s.Sections.add(p.Section(), WeightedPage{s.Pages[i].Weight, s.Pages[i]}, s.Info.preserveTaxonomyNames)
|
section := p.Section()
|
||||||
|
if s.isTaxonomy(section) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s.Sections.add(section, WeightedPage{s.Pages[i].Weight, regularPages[i]}, s.Info.preserveTaxonomyNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
for k := range s.Sections {
|
for k := range s.Sections {
|
||||||
|
@ -1588,6 +1599,23 @@ func (s *Site) assembleSections() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Site) isTaxonomy(section string) bool {
|
||||||
|
if _, isTaxonomy := s.Taxonomies[section]; isTaxonomy {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Site) findPagesByNodeType(n NodeType) Pages {
|
||||||
|
var pages Pages
|
||||||
|
for _, p := range s.Pages {
|
||||||
|
if p.NodeType == n {
|
||||||
|
pages = append(pages, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pages
|
||||||
|
}
|
||||||
|
|
||||||
// renderAliases renders shell pages that simply have a redirect in the header.
|
// renderAliases renders shell pages that simply have a redirect in the header.
|
||||||
func (s *Site) renderAliases() error {
|
func (s *Site) renderAliases() error {
|
||||||
for _, p := range s.Pages {
|
for _, p := range s.Pages {
|
||||||
|
@ -1645,59 +1673,6 @@ func (s *Site) preparePages() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// renderPages renders pages each corresponding to a markdown file.
|
|
||||||
func (s *Site) renderPages() error {
|
|
||||||
|
|
||||||
results := make(chan error)
|
|
||||||
pages := make(chan *Page)
|
|
||||||
errs := make(chan error)
|
|
||||||
|
|
||||||
go errorCollator(results, errs)
|
|
||||||
|
|
||||||
procs := getGoMaxProcs()
|
|
||||||
|
|
||||||
wg := &sync.WaitGroup{}
|
|
||||||
|
|
||||||
for i := 0; i < procs*4; i++ {
|
|
||||||
wg.Add(1)
|
|
||||||
go pageRenderer(s, pages, results, wg)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, page := range s.Pages {
|
|
||||||
pages <- page
|
|
||||||
}
|
|
||||||
|
|
||||||
close(pages)
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
close(results)
|
|
||||||
|
|
||||||
err := <-errs
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error(s) rendering pages: %s", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.WaitGroup) {
|
|
||||||
defer wg.Done()
|
|
||||||
for p := range pages {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.NodeType.IsNode() {
|
|
||||||
if err := p.renderPaginator(s); err != nil {
|
|
||||||
results <- err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func errorCollator(results <-chan error, errs chan<- error) {
|
func errorCollator(results <-chan error, errs chan<- error) {
|
||||||
errMsgs := []string{}
|
errMsgs := []string{}
|
||||||
for err := range results {
|
for err := range results {
|
||||||
|
@ -1753,6 +1728,9 @@ type taxRenderInfo struct {
|
||||||
// renderTaxonomiesLists renders the listing pages based on the meta data
|
// renderTaxonomiesLists renders the listing pages based on the meta data
|
||||||
// each unique term within a taxonomy will have a page created
|
// each unique term within a taxonomy will have a page created
|
||||||
func (s *Site) renderTaxonomiesLists(prepare bool) error {
|
func (s *Site) renderTaxonomiesLists(prepare bool) error {
|
||||||
|
if nodePageFeatureFlag {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
|
|
||||||
taxes := make(chan taxRenderInfo)
|
taxes := make(chan taxRenderInfo)
|
||||||
|
|
122
hugolib/site_render.go
Normal file
122
hugolib/site_render.go
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
// Copyright 2016 The Hugo Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package hugolib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/spf13/hugo/helpers"
|
||||||
|
|
||||||
|
jww "github.com/spf13/jwalterweatherman"
|
||||||
|
)
|
||||||
|
|
||||||
|
// renderPages renders pages each corresponding to a markdown file.
|
||||||
|
// TODO(bep np doc
|
||||||
|
func (s *Site) renderPages() error {
|
||||||
|
|
||||||
|
results := make(chan error)
|
||||||
|
pages := make(chan *Page)
|
||||||
|
errs := make(chan error)
|
||||||
|
|
||||||
|
go errorCollator(results, errs)
|
||||||
|
|
||||||
|
procs := getGoMaxProcs()
|
||||||
|
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
|
||||||
|
for i := 0; i < procs*4; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go pageRenderer(s, pages, results, wg)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, page := range s.Pages {
|
||||||
|
pages <- page
|
||||||
|
}
|
||||||
|
|
||||||
|
close(pages)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
close(results)
|
||||||
|
|
||||||
|
err := <-errs
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error(s) rendering pages: %s", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func pageRenderer(s *Site, pages <-chan *Page, results chan<- error, wg *sync.WaitGroup) {
|
||||||
|
defer wg.Done()
|
||||||
|
for p := range pages {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.NodeType.IsNode() {
|
||||||
|
if err := s.renderPaginator(p); err != nil {
|
||||||
|
results <- err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// renderPaginator must be run after the owning Page has been rendered.
|
||||||
|
// TODO(bep) np
|
||||||
|
func (s *Site) renderPaginator(p *Page) error {
|
||||||
|
if p.paginator != nil {
|
||||||
|
jww.DEBUG.Printf("Render paginator for page %q", p.Path())
|
||||||
|
paginatePath := helpers.Config().GetString("paginatePath")
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
|
||||||
|
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 := 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 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in a new issue