Nested sections / API methods / naming feedback wanted

So re. the ongoing development of nested sections (see https://github.com/spf13/hugo/pull/3309), I have introduced some new template API. Most I’m pretty happy about, some not so much, maybe. I’ll list the important bits here.

  • .Page.Sections will give you the sections (which is a Page) below that given page section. This is only relevant for the home page and the section pages.
  • .Site.Home; .Site.Sections (which today is a taxonomy) is now deprecated, and to easily get to the top level sections I have added Home, so you can then do for range .Site.Home.Sections, .Site.Home.RelPermalink etc.
    .Page.Parent will for a section navigate one level up. For the top level sections (e.g. “blog”), this will navigate to the home page.
  • .Page.Current Not happy with this name which returns a pointer to the section the page belongs to. .Section would be better, but that is taken.
  • .Page.IsActive "another page" Not totally happy with this name See https://github.com/bep/hugotest/blob/master/layouts/partials/sections-nav.html#L6 Typical use case would be to build bread crumbs navigation; it tells you if a given page belongs to the same section as the current (or the “.”).
  • .Page.IsSection; whether a page is a … section.

Also, to complete the above we have the existing method:

  • .Site.GetPage "section" "top-level" "level2" to get a specific section.

Would .Page.Parent suggest higher up the tree, or would that work instead of .Current?

The sections are now a node tree with regular pages as leaf nodes – the root being the home page.

  • So .Page.Parent = the parent node, a way to navigate from the leaf node up to the home page.
  • I’m not sure the .Page.Current very useful on its own (it is used by .Page.IsActive), but it is a way to navigate to the current section – and since it is a Go pointer you can do super-fast comparisons to other pages to check if it is the same (hence. the IsActive usage).

But those are two very different variables.

I’m trying to get my head around this, so I want to give a simple example to make sure I understand.

Given:

  • home
    • s1
      • s1p1
      • s1ss1
        • s1ss1p1
      • s1ss2
        • s1ss2p1
        • s1ss2p2

Where sX is a section, ssX is a subsection, and pX denotes a normal page.

Examples:

in template-ish pseudocode

home.Sections = [s1]
s1.Sections = [s1ss1, s1ss2]

s1ss1.Home = home

s1.Parent = home
s1ss1.Parent = s1
// s1ss1p1.Parent not supported ?

s1ss1p1.Current = *s1ss1

s1ss1p1.IsActive s1ss2p1 = false
s1ss2p1.IsActive s1ss2p2 = true

s1.IsSection = true
s1ss1.IsSection = true
s1ss1p1.IsSection = false

Am I off-base on anything above?

Questions and Comments

First of all, this is a huge feature that many have asked about in the past. Thanks for trying to tackle it.

@budparr hinted at this (I think), but .Page.Parent is a better name than .Page.Current. Every node (whether branch/section or leaf/page) should support a .Parent call, I think. Are you saying that s1ss1p1.Parent = *s1ss1 would not work?

What about .Page.IsPeer instead of IsActive? “peer” as in “one belonging to the same group.”

Only .Site.Home is currently valid.

I have tried to wrap my head around your Germany in the 40s name standard, and it is mostly correct.

  • Your IsActive examples may be correct, but does not make much sense. The typical pair would be a section and a regular page.
  • s1ss1p1.Parent = *s1

And you cannot currently rename Current to Parent … they are two different entities. I agree that “Parent” may be confusing, as it is currently really “ParentSection”.

So, after thinking about this here is the proposed change:

  • Remove Current (or unexport it)
  • Make Parent so it always takes you one step up the tree

OK, so this discussion was very useful. Stuff that made totally sense when I wrote it, is not that clever when you start to think about it.

I have redefined the Parent to always navigate to the first parent (and unexported Current so we do not have to think too hard about its name).

If you start at this regular page and push the “Up button” it should now work as expected:

http://hugotest.bep.is/second/subfirst/subsub/subsubsub/first-sub/

Re. the IsActive… Which tells if the two pages are on the same section level. Peer?

Much better. :+1:

I think I misunderstood what IsActive was doing. I thought you were trying to see if two pages were in the same section. In that case, IsPeer makes sense.

However, IsActive tests if a page belongs to a section.

So, to redo my example:

s1ss2p1.IsActive s1ss1 = false
s1ss2p1.IsActive s1ss2 = true

s1ss2p1.IsPeer s1ss1p1 = false
s1ss2p1.IsPeer s1ss2p2 = true

But you’re right, the IsActive name is not very descriptive. What about InSection or BelongsTo?

LOL. That’s essentially how we name our network equipment at work. Building+IDF#+Role+Device#. It’s handy because I can simply look at a switch name (like sm1as2) and know exactly where that device is on our campus.

OK, to take a step back and get the terms in order.

home
├── a
│   ├── a1.md
│   ├── a2.md
│   └── c
│       └── c1.md
└── b

So

  • a1. md is a leaf node, i.e. regular page
  • a1.md and a2.md are children of a, i.e. a’s Pages
  • home has two sections, a and b
  • a and b are siblings
  • a1.md and a2.md are also siblings
  • a is the parent of a1.md
  • c1.md is descendant of a
  • a is ancestor of c1.md
  • section a is active in section a.
  • section a is active when on page a1.md and a2.md
  • home is active when home
1 Like

I renamed IsActive to InSection:

Looks much better.

I’m finished now. Thanks for the help.

2 Likes

Is it worth adding IsDescendant and/or IsAnscestor?

c1.IsDescendant a = true
a.IsAnscestor c1 = true

Maybe … later. The API change is big as it is, I want to see how people use this before we commit to more. It is hard to remove stuff once it is in.

Why not .Page.CurrentSection? Or .Page.OwnSection?