Skip to content

Multi-level sections (tree) #465

@rahul286

Description

@rahul286

@spf13 Sorry in advance if you find this too long or absurd (or both).

This requests is based heavily on personal needs. I am struggling with this problem from long time. So I decided today to post this down in as much details as possible.

I came across few threads in same direction suggesting to make use of front-matters. I will explain why I think front-matters is not an optimal choice here.

Problem

I have created a sample site to explain this problem - https://github.com/rahul286/hugo-sample

Content looks like:

$ tree content
content
├── level-one
│   ├── level-two
│   │   ├── level-three
│   │   │   ├── level-four
│   │   │   │   ├── page-4-a.md
│   │   │   │   ├── page-4-b.md
│   │   │   │   └── page-4-c.md
│   │   │   ├── page-3-a.md
│   │   │   ├── page-3-b.md
│   │   │   └── page-3-c.md
│   │   ├── page-2-a.md
│   │   ├── page-2-b.md
│   │   └── page-2-c.md
│   ├── page-1-a.md
│   ├── page-1-b.md
│   └── page-1-c.md
└── page-top.md

4 directories, 13 files

As you can see there many levels at which directories and content are present.

Expected Output

What I am trying to have is...

For any folder, list down pages at immediate levels only OR at all levels.

If listing at all-levels, nested lists should be created. Something like list of pages shows on - http://rtcamp.com/tutorials/

As you can see for sample-site - http://rahul286.com/hugo-sample/level-one/ shows all pages but without any hierarchy.

At sub-levels nothing shows up: (bigger problem)

  1. http://rahul286.com/hugo-sample/level-one/level-two/
  2. http://rahul286.com/hugo-sample/level-one/level-two/level-three/
  3. http://rahul286.com/hugo-sample/level-one/level-two/level-three/level-four/

But direct link to inner-page still works - http://rahul286.com/hugo-sample/level-one/level-two/level-three/level-four/page-4-b/

This means directory structure is preserved. Just nested directories do not have an automatically generated index page.

Hugo did generate index page for top-level folder automatically as it appears - http://rahul286.com/hugo-sample/level-one/ (source - https://github.com/rahul286/hugo-sample/blob/gh-pages/level-one/index.html )

Workaround/Ideas

I think hugo has few things already in-place which generated level-one index page.

Few changes/enhancements will be needed so hugo can be used on sites with multi-level pages.

  • Extend index generation logic to any directory. May be _default/list.html template can be applied to sub-directories.
  • Provide some filter and meta-data so we can control listing itself.

I think first task will be easier (sorry if I am underestimating this, as I'm new to golang)

Second task can get tricky as different sites may wish to control list pages html differently.

  1. List all pages, subpages and subdir. Like linux tree command at that page-level. Live example, this section on one of our site: https://rtcamp.com/tutorials/ and https://rtcamp.com/tutorials/ , https://rtcamp.com/tutorials/mail/ , https://rtcamp.com/tutorials/mail/server/ and https://rtcamp.com/tutorials/mail/server/testing/ - at each level we are only showing subtree
  2. List all pages if there are no subdirectories present. May be some sites wish to show list of "immediate pages" and sub-directories only. Reason could be - there may be 1000+ pages and if we show entire tree at top-most level, it may makes top-page cluttered.
  3. In both cases above, there could be things like listing pages and sub-directories separately. Using ul/li v/s ol/li v/s something else in output html.

At code-level, hugo may extend...

.Data.Pages Variable

{{ range .Data.Pages }} may have few variants like:

{{ range .Data.Pages.SubPages }} - for immediate subpages (.Data.Pages already have all subpages i.e. entire tree)

{{ range .Data.Pages.SubDirs }} - for immediate subdirectories

{{ range .Data.Pages.SubDirsAll }} - for all subdirectories (nested)

May be we can make use of new where clause as below:

``{{ range where .Data.Pages "Level" 1 }}`

``{{ range where .Data.Pages "type" "dir" }}`

``{{ range where .Data.Pages "type" "page" }}`

Or may be group by:

{{ range .Data.Pages.GroupBy "type" "page" }}

Node variables

We may introduce some additional node variables.

For example:

.SubPagesCount - Number of subpages this
.NumLevels - Number of subdir levels
.HasSubDirs - true if current node has subdirs

Why I am not using fornt-matters?

Finally, let me add my own explanation for not using front-matters for this.

As site grows, new levels gets added for better organization. It may be needed to move pages in bulk from one-section to another-section at no-fixed-level. So if we make use of front-matters and menus, we may need to manually update each page during such moves.

While I like power of front-matters, I prefer to avoid it whenever possible. If tree-like structure can be achieved by conventional file-system hierarchy, it may reduce clutter in actual content. Also, for a contributor it will be easy to find write article on local filesystem.

Finally

Thanks for reading. :-)

Please correct/improve this wherever possible.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions