Skip to content

Commit b396893

Browse files
committed
hugolib: Enable nested sections
Fixes #465
1 parent bef5048 commit b396893

File tree

11 files changed

+635
-183
lines changed

11 files changed

+635
-183
lines changed

‎hugolib/hugo_sites.go‎

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,11 @@ func (h *HugoSites) createMissingPages() error {
337337
}
338338
}
339339

340+
// Will create content-less root sections.
341+
newSections := s.assembleSections()
342+
s.Pages = append(s.Pages, newSections...)
343+
newPages = append(newPages, newSections...)
344+
340345
// taxonomy list and terms pages
341346
taxonomies := s.Language.GetStringMapString("taxonomies")
342347
if len(taxonomies) > 0 {
@@ -384,33 +389,6 @@ func (h *HugoSites) createMissingPages() error {
384389
}
385390
}
386391
}
387-
388-
if s.isEnabled(KindSection) {
389-
sectionPages := s.findPagesByKind(KindSection)
390-
if len(sectionPages) < len(s.Sections) {
391-
for name, section := range s.Sections {
392-
// A section may be created for the root content folder if a
393-
// content file is placed there.
394-
// We cannot create a section node for that, because
395-
// that would overwrite the home page.
396-
if name == "" {
397-
continue
398-
}
399-
foundSection := false
400-
for _, sectionPage := range sectionPages {
401-
if sectionPage.sections[0] == name {
402-
foundSection = true
403-
break
404-
}
405-
}
406-
if !foundSection {
407-
n := s.newSectionPage(name, section)
408-
s.Pages = append(s.Pages, n)
409-
newPages = append(newPages, n)
410-
}
411-
}
412-
}
413-
}
414392
}
415393

416394
if len(newPages) > 0 {

‎hugolib/menu_old_test.go‎

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -402,25 +402,27 @@ func doTestSectionPagesMenu(canonifyURLs bool, t *testing.T) {
402402
"canonifyURLs", canonifyURLs,
403403
)
404404

405-
require.Equal(t, 3, len(s.Sections))
405+
sects := s.getPage(KindHome).Sections()
406406

407-
firstSectionPages := s.Sections["first"]
407+
require.Equal(t, 3, len(sects))
408+
409+
firstSectionPages := s.getPage(KindSection, "first").Pages
408410
require.Equal(t, 2, len(firstSectionPages))
409-
secondSectionPages := s.Sections["second-section"]
411+
secondSectionPages := s.getPage(KindSection, "second-section").Pages
410412
require.Equal(t, 1, len(secondSectionPages))
411-
fishySectionPages := s.Sections["fish-and-chips"]
413+
fishySectionPages := s.getPage(KindSection, "Fish and Chips").Pages
412414
require.Equal(t, 1, len(fishySectionPages))
413415

414416
nodeFirst := s.getPage(KindSection, "first")
415417
require.NotNil(t, nodeFirst)
416418
nodeSecond := s.getPage(KindSection, "second-section")
417419
require.NotNil(t, nodeSecond)
418-
nodeFishy := s.getPage(KindSection, "fish-and-chips")
419-
require.Equal(t, "fish-and-chips", nodeFishy.sections[0])
420+
nodeFishy := s.getPage(KindSection, "Fish and Chips")
421+
require.Equal(t, "Fish and Chips", nodeFishy.sections[0])
420422

421423
firstSectionMenuEntry := findTestMenuEntryByID(s, "spm", "first")
422424
secondSectionMenuEntry := findTestMenuEntryByID(s, "spm", "second-section")
423-
fishySectionMenuEntry := findTestMenuEntryByID(s, "spm", "fish-and-chips")
425+
fishySectionMenuEntry := findTestMenuEntryByID(s, "spm", "Fish and Chips")
424426

425427
require.NotNil(t, firstSectionMenuEntry)
426428
require.NotNil(t, secondSectionMenuEntry)
@@ -436,19 +438,19 @@ func doTestSectionPagesMenu(canonifyURLs bool, t *testing.T) {
436438
require.Equal(t, "Fish and Chips", fishySectionMenuEntry.Name)
437439

438440
for _, p := range firstSectionPages {
439-
require.True(t, p.Page.HasMenuCurrent("spm", firstSectionMenuEntry))
440-
require.False(t, p.Page.HasMenuCurrent("spm", secondSectionMenuEntry))
441+
require.True(t, p.HasMenuCurrent("spm", firstSectionMenuEntry))
442+
require.False(t, p.HasMenuCurrent("spm", secondSectionMenuEntry))
441443
}
442444

443445
for _, p := range secondSectionPages {
444-
require.False(t, p.Page.HasMenuCurrent("spm", firstSectionMenuEntry))
445-
require.True(t, p.Page.HasMenuCurrent("spm", secondSectionMenuEntry))
446+
require.False(t, p.HasMenuCurrent("spm", firstSectionMenuEntry))
447+
require.True(t, p.HasMenuCurrent("spm", secondSectionMenuEntry))
446448
}
447449

448450
for _, p := range fishySectionPages {
449-
require.False(t, p.Page.HasMenuCurrent("spm", firstSectionMenuEntry))
450-
require.False(t, p.Page.HasMenuCurrent("spm", secondSectionMenuEntry))
451-
require.True(t, p.Page.HasMenuCurrent("spm", fishySectionMenuEntry))
451+
require.False(t, p.HasMenuCurrent("spm", firstSectionMenuEntry))
452+
require.False(t, p.HasMenuCurrent("spm", secondSectionMenuEntry))
453+
require.True(t, p.HasMenuCurrent("spm", fishySectionMenuEntry))
452454
}
453455
}
454456

‎hugolib/page.go‎

Lines changed: 66 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ type Page struct {
175175
// isn't accomanied by one.
176176
sections []string
177177

178+
// Will only be set for sections and regular pages.
179+
parent *Page
180+
181+
// When we create paginator pages, we create a copy of the original,
182+
// but keep track of it here.
183+
origOnCopy *Page
184+
185+
// Will only be set for section pages and the home page.
186+
subSections Pages
187+
178188
s *Site
179189

180190
// Pulled over from old Node. TODO(bep) reorg and group (embed)
@@ -228,6 +238,9 @@ func (p *Page) createLayoutDescriptor() output.LayoutDescriptor {
228238

229239
switch p.Kind {
230240
case KindSection:
241+
// In Hugo 0.22 we introduce nested sections, but we still only
242+
// use the first level to pick the correct template. This may change in
243+
// the future.
231244
section = p.sections[0]
232245
case KindTaxonomy, KindTaxonomyTerm:
233246
section = p.s.taxonomiesPluralSingular[p.sections[0]]
@@ -265,6 +278,11 @@ func (p *Page) IsHome() bool {
265278
return p.Kind == KindHome
266279
}
267280

281+
// IsSection returns whether this is a section page.
282+
func (p *Page) IsSection() bool {
283+
return p.Kind == KindSection
284+
}
285+
268286
// IsPage returns whether this is a regular content page.
269287
func (p *Page) IsPage() bool {
270288
return p.Kind == KindPage
@@ -667,6 +685,9 @@ func (p *Page) Type() string {
667685
return "page"
668686
}
669687

688+
// Section returns the first path element below the content root. Note that
689+
// since Hugo 0.22 we support nested sections, but this will always be the first
690+
// element of any nested path.
670691
func (p *Page) Section() string {
671692
if p.Kind == KindSection {
672693
return p.sections[0]
@@ -1100,10 +1121,6 @@ func (p *Page) HasMenuCurrent(menuID string, me *MenuEntry) bool {
11001121
if sectionPagesMenu != "" {
11011122
section := p.Section()
11021123

1103-
if !p.s.Info.preserveTaxonomyNames {
1104-
section = p.s.PathSpec.MakePathSanitized(section)
1105-
}
1106-
11071124
if section != "" && sectionPagesMenu == menuID && section == me.Identifier {
11081125
return true
11091126
}
@@ -1415,59 +1432,54 @@ func (p *Page) prepareLayouts() error {
14151432
}
14161433

14171434
func (p *Page) prepareData(s *Site) error {
1418-
1419-
var pages Pages
1420-
1421-
p.Data = make(map[string]interface{})
1422-
switch p.Kind {
1423-
case KindPage:
1424-
case KindHome:
1425-
pages = s.RegularPages
1426-
case KindSection:
1427-
sectionData, ok := s.Sections[p.Section()]
1428-
if !ok {
1429-
return fmt.Errorf("Data for section %s not found", p.Section())
1430-
}
1431-
pages = sectionData.Pages()
1432-
case KindTaxonomy:
1433-
plural := p.sections[0]
1434-
term := p.sections[1]
1435-
1436-
if s.Info.preserveTaxonomyNames {
1437-
if v, ok := s.taxonomiesOrigKey[fmt.Sprintf("%s-%s", plural, term)]; ok {
1438-
term = v
1435+
if p.Kind != KindSection {
1436+
var pages Pages
1437+
p.Data = make(map[string]interface{})
1438+
1439+
switch p.Kind {
1440+
case KindPage:
1441+
case KindHome:
1442+
pages = s.RegularPages
1443+
case KindTaxonomy:
1444+
plural := p.sections[0]
1445+
term := p.sections[1]
1446+
1447+
if s.Info.preserveTaxonomyNames {
1448+
if v, ok := s.taxonomiesOrigKey[fmt.Sprintf("%s-%s", plural, term)]; ok {
1449+
term = v
1450+
}
14391451
}
1440-
}
14411452

1442-
singular := s.taxonomiesPluralSingular[plural]
1443-
taxonomy := s.Taxonomies[plural].Get(term)
1444-
1445-
p.Data[singular] = taxonomy
1446-
p.Data["Singular"] = singular
1447-
p.Data["Plural"] = plural
1448-
p.Data["Term"] = term
1449-
pages = taxonomy.Pages()
1450-
case KindTaxonomyTerm:
1451-
plural := p.sections[0]
1452-
singular := s.taxonomiesPluralSingular[plural]
1453-
1454-
p.Data["Singular"] = singular
1455-
p.Data["Plural"] = plural
1456-
p.Data["Terms"] = s.Taxonomies[plural]
1457-
// keep the following just for legacy reasons
1458-
p.Data["OrderedIndex"] = p.Data["Terms"]
1459-
p.Data["Index"] = p.Data["Terms"]
1460-
1461-
// A list of all KindTaxonomy pages with matching plural
1462-
for _, p := range s.findPagesByKind(KindTaxonomy) {
1463-
if p.sections[0] == plural {
1464-
pages = append(pages, p)
1453+
singular := s.taxonomiesPluralSingular[plural]
1454+
taxonomy := s.Taxonomies[plural].Get(term)
1455+
1456+
p.Data[singular] = taxonomy
1457+
p.Data["Singular"] = singular
1458+
p.Data["Plural"] = plural
1459+
p.Data["Term"] = term
1460+
pages = taxonomy.Pages()
1461+
case KindTaxonomyTerm:
1462+
plural := p.sections[0]
1463+
singular := s.taxonomiesPluralSingular[plural]
1464+
1465+
p.Data["Singular"] = singular
1466+
p.Data["Plural"] = plural
1467+
p.Data["Terms"] = s.Taxonomies[plural]
1468+
// keep the following just for legacy reasons
1469+
p.Data["OrderedIndex"] = p.Data["Terms"]
1470+
p.Data["Index"] = p.Data["Terms"]
1471+
1472+
// A list of all KindTaxonomy pages with matching plural
1473+
for _, p := range s.findPagesByKind(KindTaxonomy) {
1474+
if p.sections[0] == plural {
1475+
pages = append(pages, p)
1476+
}
14651477
}
14661478
}
1467-
}
14681479

1469-
p.Data["Pages"] = pages
1470-
p.Pages = pages
1480+
p.Data["Pages"] = pages
1481+
p.Pages = pages
1482+
}
14711483

14721484
// Now we know enough to set missing dates on home page etc.
14731485
p.updatePageDates()
@@ -1736,11 +1748,8 @@ func (p *Page) setValuesForKind(s *Site) {
17361748
switch p.Kind {
17371749
case KindHome:
17381750
p.URLPath.URL = "/"
1739-
case KindSection:
1740-
p.URLPath.URL = "/" + p.sections[0] + "/"
1741-
case KindTaxonomy:
1742-
p.URLPath.URL = "/" + path.Join(p.sections...) + "/"
1743-
case KindTaxonomyTerm:
1751+
case KindPage:
1752+
default:
17441753
p.URLPath.URL = "/" + path.Join(p.sections...) + "/"
17451754
}
17461755
}

‎hugolib/page_collections.go‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ func (c *PageCollections) getPage(typ string, sections ...string) *Page {
101101
key = path.Join(sections...)
102102
}
103103

104-
// TODO(bep) section error
105104
p, _ := c.pageCache.Get(typ, key)
106105
if p == nil {
107106
return nil

0 commit comments

Comments
 (0)