summaryrefslogtreecommitdiffstats
path: root/hugolib/pagecollections.go
diff options
context:
space:
mode:
Diffstat (limited to 'hugolib/pagecollections.go')
-rw-r--r--hugolib/pagecollections.go200
1 files changed, 191 insertions, 9 deletions
diff --git a/hugolib/pagecollections.go b/hugolib/pagecollections.go
index aedcf4090..1c8bed9d9 100644
--- a/hugolib/pagecollections.go
+++ b/hugolib/pagecollections.go
@@ -17,8 +17,12 @@ import (
"fmt"
"path"
"path/filepath"
+ "sort"
"strings"
"sync"
+ "time"
+
+ "github.com/gohugoio/hugo/resources/resource"
"github.com/pkg/errors"
@@ -32,6 +36,7 @@ var ambiguityFlag = &pageState{}
// PageCollections contains the page collections for a site.
type PageCollections struct {
+ pagesMap *pagesMap
// Includes absolute all pages (of all types), including drafts etc.
rawAllPages pageStatePages
@@ -340,15 +345,6 @@ func (*PageCollections) findPagesByKindInWorkPages(kind string, inPages pageStat
return pages
}
-func (c *PageCollections) findFirstWorkPageByKindIn(kind string) *pageState {
- for _, p := range c.workAllPages {
- if p.Kind() == kind {
- return p
- }
- }
- return nil
-}
-
func (c *PageCollections) addPage(page *pageState) {
c.rawAllPages = append(c.rawAllPages, page)
}
@@ -389,3 +385,189 @@ func (c *PageCollections) clearResourceCacheForPage(page *pageState) {
page.s.ResourceSpec.DeleteCacheByPrefix(page.targetPaths().SubResourceBaseTarget)
}
}
+
+func (c *PageCollections) assemblePagesMap(s *Site) error {
+ c.pagesMap = newPagesMap(s)
+
+ rootSections := make(map[string]bool)
+
+ // Add all branch nodes first.
+ for _, p := range c.rawAllPages {
+ rootSections[p.Section()] = true
+ if p.IsPage() {
+ continue
+ }
+ c.pagesMap.addPage(p)
+ }
+
+ // Create missing home page and the first level sections if no
+ // _index provided.
+ s.home = c.pagesMap.getOrCreateHome()
+ for k := range rootSections {
+ c.pagesMap.createSectionIfNotExists(k)
+ }
+
+ // Attach the regular pages to their section.
+ for _, p := range c.rawAllPages {
+ if p.IsNode() {
+ continue
+ }
+ c.pagesMap.addPage(p)
+ }
+
+ return nil
+}
+
+func (c *PageCollections) createWorkAllPages() error {
+ c.workAllPages = make(pageStatePages, 0, len(c.rawAllPages))
+ c.headlessPages = make(pageStatePages, 0)
+
+ var (
+ homeDates *resource.Dates
+ sectionDates *resource.Dates
+ siteLastmod time.Time
+ siteLastDate time.Time
+
+ sectionsParamId = "mainSections"
+ sectionsParamIdLower = strings.ToLower(sectionsParamId)
+ )
+
+ mainSections, mainSectionsFound := c.pagesMap.s.Info.Params()[sectionsParamIdLower]
+
+ var (
+ bucketsToRemove []string
+ rootBuckets []*pagesMapBucket
+ )
+
+ c.pagesMap.r.Walk(func(s string, v interface{}) bool {
+ bucket := v.(*pagesMapBucket)
+ var parentBucket *pagesMapBucket
+
+ if s != "/" {
+ _, parentv, found := c.pagesMap.r.LongestPrefix(path.Dir(s))
+ if !found {
+ panic(fmt.Sprintf("[BUG] parent bucket not found for %q", s))
+ }
+ parentBucket = parentv.(*pagesMapBucket)
+
+ if !mainSectionsFound && strings.Count(s, "/") == 1 {
+ // Root section
+ rootBuckets = append(rootBuckets, bucket)
+ }
+ }
+
+ if bucket.owner.IsHome() {
+ if resource.IsZeroDates(bucket.owner) {
+ // Calculate dates from the page tree.
+ homeDates = &bucket.owner.m.Dates
+ }
+ }
+
+ sectionDates = nil
+ if resource.IsZeroDates(bucket.owner) {
+ sectionDates = &bucket.owner.m.Dates
+ }
+
+ if parentBucket != nil {
+ bucket.parent = parentBucket
+ if bucket.owner.IsSection() {
+ parentBucket.bucketSections = append(parentBucket.bucketSections, bucket)
+ }
+ }
+
+ tmp := bucket.pages[:0]
+ for _, x := range bucket.pages {
+ if c.pagesMap.s.shouldBuild(x) {
+ tmp = append(tmp, x)
+ }
+ }
+ bucket.pages = tmp
+
+ if bucket.isEmpty() {
+ if bucket.owner.IsSection() && bucket.owner.File().IsZero() {
+ // Check for any nested section.
+ var hasDescendant bool
+ c.pagesMap.r.WalkPrefix(s, func(ss string, v interface{}) bool {
+ if s != ss {
+ hasDescendant = true
+ return true
+ }
+ return false
+ })
+ if !hasDescendant {
+ // This is an auto-created section with, now, nothing in it.
+ bucketsToRemove = append(bucketsToRemove, s)
+ return false
+ }
+ }
+ }
+
+ if !bucket.disabled {
+ c.workAllPages = append(c.workAllPages, bucket.owner)
+ }
+
+ if !bucket.view {
+ for _, p := range bucket.pages {
+ ps := p.(*pageState)
+ ps.parent = bucket.owner
+ if ps.m.headless {
+ c.headlessPages = append(c.headlessPages, ps)
+ } else {
+ c.workAllPages = append(c.workAllPages, ps)
+ }
+
+ if homeDates != nil {
+ homeDates.UpdateDateAndLastmodIfAfter(ps)
+ }
+
+ if sectionDates != nil {
+ sectionDates.UpdateDateAndLastmodIfAfter(ps)
+ }
+
+ if p.Lastmod().After(siteLastmod) {
+ siteLastmod = p.Lastmod()
+ }
+ if p.Date().After(siteLastDate) {
+ siteLastDate = p.Date()
+ }
+ }
+ }
+
+ return false
+ })
+
+ c.pagesMap.s.lastmod = siteLastmod
+
+ if !mainSectionsFound {
+
+ // Calculare main section
+ var (
+ maxRootBucketWeight int
+ maxRootBucket *pagesMapBucket
+ )
+
+ for _, b := range rootBuckets {
+ weight := len(b.pages) + (len(b.bucketSections) * 5)
+ if weight >= maxRootBucketWeight {
+ maxRootBucket = b
+ maxRootBucketWeight = weight
+ }
+ }
+
+ if maxRootBucket != nil {
+ // Try to make this as backwards compatible as possible.
+ mainSections = []string{maxRootBucket.owner.Section()}
+ }
+ }
+
+ c.pagesMap.s.Info.Params()[sectionsParamId] = mainSections
+ c.pagesMap.s.Info.Params()[sectionsParamIdLower] = mainSections
+
+ for _, key := range bucketsToRemove {
+ c.pagesMap.r.Delete(key)
+ }
+
+ sort.Sort(c.workAllPages)
+
+ return nil
+}