diff options
Diffstat (limited to 'hugolib/pages_map.go')
-rw-r--r-- | hugolib/pages_map.go | 474 |
1 files changed, 0 insertions, 474 deletions
diff --git a/hugolib/pages_map.go b/hugolib/pages_map.go deleted file mode 100644 index 57b50cdee..000000000 --- a/hugolib/pages_map.go +++ /dev/null @@ -1,474 +0,0 @@ -// Copyright 2019 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" - "strings" - "sync" - - "github.com/gohugoio/hugo/common/maps" - - radix "github.com/armon/go-radix" - "github.com/spf13/cast" - - "github.com/gohugoio/hugo/resources/page" -) - -func newPagesMap(s *Site) *pagesMap { - return &pagesMap{ - r: radix.New(), - s: s, - } -} - -type pagesMap struct { - r *radix.Tree - s *Site -} - -func (m *pagesMap) Get(key string) *pagesMapBucket { - key = m.cleanKey(key) - v, found := m.r.Get(key) - if !found { - return nil - } - - return v.(*pagesMapBucket) -} - -func (m *pagesMap) getKey(p *pageState) string { - if !p.File().IsZero() { - return m.cleanKey(p.File().Dir()) - } - return m.cleanKey(p.SectionsPath()) -} - -func (m *pagesMap) getOrCreateHome() *pageState { - var home *pageState - b, found := m.r.Get("/") - if !found { - home = m.s.newPage(page.KindHome) - m.addBucketFor("/", home, nil) - } else { - home = b.(*pagesMapBucket).owner - } - - return home -} - -func (m *pagesMap) initPageMeta(p *pageState, bucket *pagesMapBucket) error { - var err error - p.metaInit.Do(func() { - if p.metaInitFn != nil { - err = p.metaInitFn(bucket) - } - }) - return err -} - -func (m *pagesMap) initPageMetaFor(prefix string, bucket *pagesMapBucket) error { - parentBucket := m.parentBucket(prefix) - - m.mergeCascades(bucket, parentBucket) - - if err := m.initPageMeta(bucket.owner, bucket); err != nil { - return err - } - - if !bucket.view { - for _, p := range bucket.pages { - ps := p.(*pageState) - if err := m.initPageMeta(ps, bucket); err != nil { - return err - } - - for _, p := range ps.resources.ByType(pageResourceType) { - if err := m.initPageMeta(p.(*pageState), bucket); err != nil { - return err - } - } - } - - // Now that the metadata is initialized (with dates, draft set etc.) - // we can remove the pages that we for some reason should not include - // in this build. - tmp := bucket.pages[:0] - for _, x := range bucket.pages { - if m.s.shouldBuild(x) { - if x.(*pageState).m.headless { - bucket.headlessPages = append(bucket.headlessPages, x) - } else { - tmp = append(tmp, x) - } - - } - } - bucket.pages = tmp - } - - return nil -} - -func (m *pagesMap) createSectionIfNotExists(section string) { - key := m.cleanKey(section) - _, found := m.r.Get(key) - if !found { - kind := m.s.kindFromSectionPath(section) - p := m.s.newPage(kind, section) - m.addBucketFor(key, p, nil) - } -} - -func (m *pagesMap) addBucket(p *pageState) { - key := m.getKey(p) - - m.addBucketFor(key, p, nil) -} - -func (m *pagesMap) addBucketFor(key string, p *pageState, meta map[string]interface{}) *pagesMapBucket { - var isView bool - switch p.Kind() { - case page.KindTaxonomy, page.KindTaxonomyTerm: - isView = true - } - - disabled := !m.s.isEnabled(p.Kind()) - - var cascade map[string]interface{} - if p.bucket != nil { - cascade = p.bucket.cascade - } - - bucket := &pagesMapBucket{ - owner: p, - view: isView, - cascade: cascade, - meta: meta, - disabled: disabled, - } - - p.bucket = bucket - - m.r.Insert(key, bucket) - - return bucket -} - -func (m *pagesMap) addPage(p *pageState) { - if !p.IsPage() { - m.addBucket(p) - return - } - - if !m.s.isEnabled(page.KindPage) { - return - } - - key := m.getKey(p) - - var bucket *pagesMapBucket - - _, v, found := m.r.LongestPrefix(key) - if !found { - panic(fmt.Sprintf("[BUG] bucket with key %q not found", key)) - } - - bucket = v.(*pagesMapBucket) - bucket.pages = append(bucket.pages, p) -} - -func (m *pagesMap) assemblePageMeta() error { - var walkErr error - m.r.Walk(func(s string, v interface{}) bool { - bucket := v.(*pagesMapBucket) - - if err := m.initPageMetaFor(s, bucket); err != nil { - walkErr = err - return true - } - return false - }) - - return walkErr -} - -func (m *pagesMap) assembleTaxonomies(s *Site) error { - s.Taxonomies = make(TaxonomyList) - - type bucketKey struct { - plural string - termKey string - } - - // Temporary cache. - taxonomyBuckets := make(map[bucketKey]*pagesMapBucket) - - for singular, plural := range s.siteCfg.taxonomiesConfig { - s.Taxonomies[plural] = make(Taxonomy) - bkey := bucketKey{ - plural: plural, - } - - bucket := m.Get(plural) - - if bucket == nil { - // Create the page and bucket - n := s.newPage(page.KindTaxonomyTerm, plural) - - key := m.cleanKey(plural) - bucket = m.addBucketFor(key, n, nil) - if err := m.initPageMetaFor(key, bucket); err != nil { - return err - } - } - - if bucket.meta == nil { - bucket.meta = map[string]interface{}{ - "singular": singular, - "plural": plural, - } - } - - // Add it to the temporary cache. - taxonomyBuckets[bkey] = bucket - - // Taxonomy entries used in page front matter will be picked up later, - // but there may be some yet to be used. - pluralPrefix := m.cleanKey(plural) + "/" - m.r.WalkPrefix(pluralPrefix, func(k string, v interface{}) bool { - tb := v.(*pagesMapBucket) - termKey := strings.TrimPrefix(k, pluralPrefix) - if tb.meta == nil { - tb.meta = map[string]interface{}{ - "singular": singular, - "plural": plural, - "term": tb.owner.Title(), - "termKey": termKey, - } - } - - bucket.pages = append(bucket.pages, tb.owner) - bkey.termKey = termKey - taxonomyBuckets[bkey] = tb - - return false - }) - - } - - addTaxonomy := func(singular, plural, term string, weight int, p page.Page) error { - bkey := bucketKey{ - plural: plural, - } - - termKey := s.getTaxonomyKey(term) - - b1 := taxonomyBuckets[bkey] - - var b2 *pagesMapBucket - bkey.termKey = termKey - b, found := taxonomyBuckets[bkey] - if found { - b2 = b - } else { - - // Create the page and bucket - n := s.newTaxonomyPage(term, plural, termKey) - meta := map[string]interface{}{ - "singular": singular, - "plural": plural, - "term": term, - "termKey": termKey, - } - - key := m.cleanKey(path.Join(plural, termKey)) - b2 = m.addBucketFor(key, n, meta) - if err := m.initPageMetaFor(key, b2); err != nil { - return err - } - b1.pages = append(b1.pages, b2.owner) - taxonomyBuckets[bkey] = b2 - - } - - w := page.NewWeightedPage(weight, p, b2.owner) - - s.Taxonomies[plural].add(termKey, w) - - b1.owner.m.Dates.UpdateDateAndLastmodIfAfter(p) - b2.owner.m.Dates.UpdateDateAndLastmodIfAfter(p) - - return nil - } - - m.r.Walk(func(k string, v interface{}) bool { - b := v.(*pagesMapBucket) - if b.view { - return false - } - - for singular, plural := range s.siteCfg.taxonomiesConfig { - for _, p := range b.pages { - - vals := getParam(p, plural, false) - - w := getParamToLower(p, plural+"_weight") - weight, err := cast.ToIntE(w) - if err != nil { - m.s.Log.ERROR.Printf("Unable to convert taxonomy weight %#v to int for %q", w, p.Path()) - // weight will equal zero, so let the flow continue - } - - if vals != nil { - if v, ok := vals.([]string); ok { - for _, idx := range v { - if err := addTaxonomy(singular, plural, idx, weight, p); err != nil { - m.s.Log.ERROR.Printf("Failed to add taxonomy %q for %q: %s", plural, p.Path(), err) - } - } - } else if v, ok := vals.(string); ok { - if err := addTaxonomy(singular, plural, v, weight, p); err != nil { - m.s.Log.ERROR.Printf("Failed to add taxonomy %q for %q: %s", plural, p.Path(), err) - } - } else { - m.s.Log.ERROR.Printf("Invalid %s in %q\n", plural, p.Path()) - } - } - - } - } - return false - }) - - for _, plural := range s.siteCfg.taxonomiesConfig { - for k := range s.Taxonomies[plural] { - s.Taxonomies[plural][k].Sort() - } - } - - return nil -} - -func (m *pagesMap) cleanKey(key string) string { - key = filepath.ToSlash(strings.ToLower(key)) - key = strings.Trim(key, "/") - return "/" + key -} - -func (m *pagesMap) mergeCascades(b1, b2 *pagesMapBucket) { - if b1.cascade == nil { - b1.cascade = make(maps.Params) - } - if b2 != nil && b2.cascade != nil { - for k, v := range b2.cascade { - if _, found := b1.cascade[k]; !found { - b1.cascade[k] = v - } - } - } -} - -func (m *pagesMap) parentBucket(prefix string) *pagesMapBucket { - if prefix == "/" { - return nil - } - _, parentv, found := m.r.LongestPrefix(path.Dir(prefix)) - if !found { - panic(fmt.Sprintf("[BUG] parent bucket not found for %q", prefix)) - } - return parentv.(*pagesMapBucket) - -} - -func (m *pagesMap) withEveryPage(f func(p *pageState)) { - m.r.Walk(func(k string, v interface{}) bool { - b := v.(*pagesMapBucket) - f(b.owner) - if !b.view { - for _, p := range b.pages { - f(p.(*pageState)) - } - } - - return false - }) -} - -type pagesMapBucket struct { - // Set if the pages in this bucket is also present in another bucket. - view bool - - // Some additional metatadata attached to this node. - meta map[string]interface{} - - // Cascading front matter. - cascade map[string]interface{} - - owner *pageState // The branch node - - // When disableKinds is enabled for this node. - disabled bool - - // Used to navigate the sections tree - parent *pagesMapBucket - bucketSections []*pagesMapBucket - - pagesInit sync.Once - pages page.Pages - headlessPages page.Pages - - pagesAndSectionsInit sync.Once - pagesAndSections page.Pages - - sectionsInit sync.Once - sections page.Pages -} - -func (b *pagesMapBucket) isEmpty() bool { - return len(b.pages) == 0 && len(b.headlessPages) == 0 && len(b.bucketSections) == 0 -} - -func (b *pagesMapBucket) getPages() page.Pages { - b.pagesInit.Do(func() { - page.SortByDefault(b.pages) - }) - return b.pages -} - -func (b *pagesMapBucket) getPagesAndSections() page.Pages { - b.pagesAndSectionsInit.Do(func() { - var pas page.Pages - pas = append(pas, b.getPages()...) - for _, p := range b.bucketSections { - pas = append(pas, p.owner) - } - b.pagesAndSections = pas - page.SortByDefault(b.pagesAndSections) - }) - return b.pagesAndSections -} - -func (b *pagesMapBucket) getSections() page.Pages { - b.sectionsInit.Do(func() { - for _, p := range b.bucketSections { - b.sections = append(b.sections, p.owner) - } - page.SortByDefault(b.sections) - }) - - return b.sections -} |