diff --git a/docs/content/en/content-management/sections.md b/docs/content/en/content-management/sections.md index 5ff884610..b68a5bdb9 100644 --- a/docs/content/en/content-management/sections.md +++ b/docs/content/en/content-management/sections.md @@ -63,19 +63,16 @@ If you need a specific template for a sub-section, you need to adjust either the With the available [section variables and methods](#section-page-variables-and-methods) you can build powerful navigation. One common example would be a partial to show Breadcrumb navigation: {{< code file="layouts/partials/breadcrumb.html" download="breadcrumb.html" >}} - -{{ define "breadcrumbnav" }} -{{ if .p1.Parent }} -{{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) }} -{{ else if not .p1.IsHome }} -{{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) }} -{{ end }} - - {{ .p1.Title }} + {{< /code >}} ## Section Page Variables and Methods diff --git a/docs/content/en/variables/page.md b/docs/content/en/variables/page.md index 07acc4831..2de54ff8b 100644 --- a/docs/content/en/variables/page.md +++ b/docs/content/en/variables/page.md @@ -32,6 +32,9 @@ See [`.Scratch`](/functions/scratch/) for page-scoped, writable variables. .Aliases : aliases of this page +.Ancestors +: get the ancestors of each page, simplify [breadcrumb navigation]({{< relref "content-management/sections#example-breadcrumb-navigation" >}}) implementation complexity + .BundleType : the [bundle] type: `leaf`, `branch`, or an empty string if the page is not a bundle. diff --git a/hugolib/page__tree.go b/hugolib/page__tree.go index 828500e62..6acd649fd 100644 --- a/hugolib/page__tree.go +++ b/hugolib/page__tree.go @@ -178,6 +178,15 @@ func (pt pageTree) Parent() page.Page { return b.p } +func (pt pageTree) Ancestors() (parents page.Pages) { + parent := pt.Parent() + for parent != nil { + parents = append(parents, parent) + parent = parent.Parent() + } + return +} + func (pt pageTree) Sections() page.Pages { if pt.p.bucket == nil { return nil diff --git a/hugolib/site_sections_test.go b/hugolib/site_sections_test.go index 2a4c39533..ccc8c51cb 100644 --- a/hugolib/site_sections_test.go +++ b/hugolib/site_sections_test.go @@ -181,12 +181,14 @@ PAG|{{ .Title }}|{{ $sect.InSection . }} c.Assert(err, qt.IsNil) c.Assert(active, qt.Equals, true) c.Assert(p.FirstSection(), qt.Equals, p) + c.Assert(len(p.Ancestors()), qt.Equals, 1) }}, {"l1", func(c *qt.C, p page.Page) { c.Assert(p.Title(), qt.Equals, "L1s") c.Assert(len(p.Pages()), qt.Equals, 4) // 2 pages + 2 sections c.Assert(p.Parent().IsHome(), qt.Equals, true) c.Assert(len(p.Sections()), qt.Equals, 2) + c.Assert(len(p.Ancestors()), qt.Equals, 1) }}, {"l1,l2", func(c *qt.C, p page.Page) { c.Assert(p.Title(), qt.Equals, "T2_-1") @@ -195,6 +197,7 @@ PAG|{{ .Title }}|{{ $sect.InSection . }} c.Assert(p.Parent().Title(), qt.Equals, "L1s") c.Assert(p.RelPermalink(), qt.Equals, "/l1/l2/") c.Assert(len(p.Sections()), qt.Equals, 1) + c.Assert(len(p.Ancestors()), qt.Equals, 2) for _, child := range p.Pages() { if child.IsSection() { @@ -237,6 +240,7 @@ PAG|{{ .Title }}|{{ $sect.InSection . }} c.Assert(p.Pages()[0].File().Path(), qt.Equals, filepath.FromSlash("l1/l2_2/page_2_2_1.md")) c.Assert(p.Parent().Title(), qt.Equals, "L1s") c.Assert(len(p.Sections()), qt.Equals, 0) + c.Assert(len(p.Ancestors()), qt.Equals, 2) }}, {"l1,l2,l3", func(c *qt.C, p page.Page) { nilp, _ := p.GetPage("this/does/not/exist") @@ -245,6 +249,7 @@ PAG|{{ .Title }}|{{ $sect.InSection . }} c.Assert(len(p.Pages()), qt.Equals, 2) c.Assert(p.Parent().Title(), qt.Equals, "T2_-1") c.Assert(len(p.Sections()), qt.Equals, 0) + c.Assert(len(p.Ancestors()), qt.Equals, 3) l1 := getPage(p, "/l1") isDescendant, err := l1.IsDescendant(p) @@ -307,6 +312,7 @@ PAG|{{ .Title }}|{{ $sect.InSection . }} } c.Assert(home, qt.Not(qt.IsNil)) + c.Assert(len(home.Ancestors()), qt.Equals, 0) c.Assert(len(home.Sections()), qt.Equals, 9) c.Assert(s.Info.Sections(), deepEqualsPages, home.Sections()) diff --git a/resources/page/page.go b/resources/page/page.go index f9b8fdcec..929f04d93 100644 --- a/resources/page/page.go +++ b/resources/page/page.go @@ -407,6 +407,9 @@ type TreeProvider interface { // To get a section's subsections, see Page's Sections method. Parent() Page + // Ancestors returns the ancestors of each page + Ancestors() Pages + // Sections returns this section's subsections, if any. // Note that for non-sections, this method will always return an empty list. Sections() Pages diff --git a/resources/page/page_nop.go b/resources/page/page_nop.go index df3227f0a..15f8c3950 100644 --- a/resources/page/page_nop.go +++ b/resources/page/page_nop.go @@ -348,6 +348,10 @@ func (p *nopPage) Parent() Page { return nil } +func (p *nopPage) Ancestors() Pages { + return nil +} + func (p *nopPage) Path() string { return "" } diff --git a/resources/page/testhelpers_test.go b/resources/page/testhelpers_test.go index 30b8e4dff..22346c389 100644 --- a/resources/page/testhelpers_test.go +++ b/resources/page/testhelpers_test.go @@ -416,6 +416,10 @@ func (p *testPage) Parent() Page { panic("not implemented") } +func (p *testPage) Ancestors() Pages { + panic("not implemented") +} + func (p *testPage) Path() string { return p.path }