page__tree.go (3473B)
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) Sections() page.Pages {
182 if pt.p.bucket == nil {
183 return nil
184 }
185
186 return pt.p.bucket.getSections()
187 }