github.com/linchen2chris/hugo@v0.0.0-20230307053224-cec209389705/hugolib/page__tree.go (about)

     1  // Copyright 2019 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package hugolib
    15  
    16  import (
    17  	"path"
    18  	"strings"
    19  
    20  	"github.com/gohugoio/hugo/common/types"
    21  	"github.com/gohugoio/hugo/resources/page"
    22  )
    23  
    24  type pageTree struct {
    25  	p *pageState
    26  }
    27  
    28  func (pt pageTree) IsAncestor(other any) (bool, error) {
    29  	if pt.p == nil {
    30  		return false, nil
    31  	}
    32  
    33  	tp, ok := other.(treeRefProvider)
    34  	if !ok {
    35  		return false, nil
    36  	}
    37  
    38  	ref1, ref2 := pt.p.getTreeRef(), tp.getTreeRef()
    39  	if ref1 != nil && ref2 != nil && ref1.key == ref2.key {
    40  		return false, nil
    41  	}
    42  
    43  	if ref1 != nil && ref1.key == "/" {
    44  		return true, nil
    45  	}
    46  
    47  	if ref1 == nil || ref2 == nil {
    48  		if ref1 == nil {
    49  			// A 404 or other similar standalone page.
    50  			return false, nil
    51  		}
    52  
    53  		return ref1.n.p.IsHome(), nil
    54  	}
    55  
    56  	if strings.HasPrefix(ref2.key, ref1.key) {
    57  		return true, nil
    58  	}
    59  
    60  	return strings.HasPrefix(ref2.key, ref1.key+cmBranchSeparator), nil
    61  }
    62  
    63  func (pt pageTree) CurrentSection() page.Page {
    64  	p := pt.p
    65  
    66  	if p.IsHome() || p.IsSection() {
    67  		return p
    68  	}
    69  
    70  	return p.Parent()
    71  }
    72  
    73  func (pt pageTree) IsDescendant(other any) (bool, error) {
    74  	if pt.p == nil {
    75  		return false, nil
    76  	}
    77  
    78  	tp, ok := other.(treeRefProvider)
    79  	if !ok {
    80  		return false, nil
    81  	}
    82  
    83  	ref1, ref2 := pt.p.getTreeRef(), tp.getTreeRef()
    84  	if ref1 != nil && ref2 != nil && ref1.key == ref2.key {
    85  		return false, nil
    86  	}
    87  
    88  	if ref2 != nil && ref2.key == "/" {
    89  		return true, nil
    90  	}
    91  
    92  	if ref1 == nil || ref2 == nil {
    93  		if ref2 == nil {
    94  			// A 404 or other similar standalone page.
    95  			return false, nil
    96  		}
    97  
    98  		return ref2.n.p.IsHome(), nil
    99  	}
   100  
   101  	if strings.HasPrefix(ref1.key, ref2.key) {
   102  		return true, nil
   103  	}
   104  
   105  	return strings.HasPrefix(ref1.key, ref2.key+cmBranchSeparator), nil
   106  }
   107  
   108  func (pt pageTree) FirstSection() page.Page {
   109  	ref := pt.p.getTreeRef()
   110  	if ref == nil {
   111  		return pt.p.s.home
   112  	}
   113  	key := ref.key
   114  
   115  	if !ref.isSection() {
   116  		key = path.Dir(key)
   117  	}
   118  
   119  	_, b := ref.m.getFirstSection(key)
   120  	if b == nil {
   121  		return nil
   122  	}
   123  	return b.p
   124  }
   125  
   126  func (pt pageTree) InSection(other any) (bool, error) {
   127  	if pt.p == nil || types.IsNil(other) {
   128  		return false, nil
   129  	}
   130  
   131  	tp, ok := other.(treeRefProvider)
   132  	if !ok {
   133  		return false, nil
   134  	}
   135  
   136  	ref1, ref2 := pt.p.getTreeRef(), tp.getTreeRef()
   137  
   138  	if ref1 == nil || ref2 == nil {
   139  		if ref1 == nil {
   140  			// A 404 or other similar standalone page.
   141  			return false, nil
   142  		}
   143  		return ref1.n.p.IsHome(), nil
   144  	}
   145  
   146  	s1, _ := ref1.getCurrentSection()
   147  	s2, _ := ref2.getCurrentSection()
   148  
   149  	return s1 == s2, nil
   150  }
   151  
   152  func (pt pageTree) Page() page.Page {
   153  	return pt.p
   154  }
   155  
   156  func (pt pageTree) Parent() page.Page {
   157  	p := pt.p
   158  
   159  	if p.parent != nil {
   160  		return p.parent
   161  	}
   162  
   163  	if pt.p.IsHome() {
   164  		return nil
   165  	}
   166  
   167  	tree := p.getTreeRef()
   168  
   169  	if tree == nil || pt.p.Kind() == page.KindTaxonomy {
   170  		return pt.p.s.home
   171  	}
   172  
   173  	_, b := tree.getSection()
   174  	if b == nil {
   175  		return nil
   176  	}
   177  
   178  	return b.p
   179  }
   180  
   181  func (pt pageTree) Ancestors() page.Pages {
   182  	var ancestors page.Pages
   183  	parent := pt.Parent()
   184  	for parent != nil {
   185  		ancestors = append(ancestors, parent)
   186  		parent = parent.Parent()
   187  	}
   188  	return ancestors
   189  }
   190  
   191  func (pt pageTree) Sections() page.Pages {
   192  	if pt.p.bucket == nil {
   193  		return nil
   194  	}
   195  
   196  	return pt.p.bucket.getSections()
   197  }