Hi folks. I’m trying to leverage Hugo for an internal documentation site. Said site will have, among other things, multiple separate trees/books or some sections but not all sections will be hierarchical.
I can build a hierarchical menu structure off of the Menu system. However, that requires manually tagging every single page with the correct menu hierarchy, giving it IDs, etc. That’s a lot of editorial work, much of which will be done by less technical people than me. And if I want to reorganize the page structure at any point it’s going to be a huge PITA to do. Basically that’s not viable from a user-experience perspective.
What I want to be able to do is build a tree based on the file structure of the markdown files. I haven’t figured out how I can accomplish that, however. That data doesn’t seem to be exposed in a useful way. I am looking for advice on how to make that data available so that I can skip having every one of my many hundreds of files having a manual menu item and structure definition, which is a no-go for my users.
For reference, here’s how I’m building a tree off of the menu:
<aside class="sidebar">
{{ $currentPage := . }}
{{ $theSection := .CurrentSection.Section }}
{{ with $activeMenu := index .Site.Menus $theSection }}
<ul>
{{ range $activeMenu }}
<li {{ if $currentPage.HasMenuCurrent $theSection . }}class="active"{{ end }}>
<a href="{{ .URL }}">
{{ .Pre }}
<span>{{ .Name }}</span>
</a>
{{ template "treesub" . }}
</li>
{{ end }}
</ul>
{{ end }}
</aside>
{{ define "treesub" }}
{{ if .HasChildren }}
<ul class="sub-menu">
{{ range .Children }}
<li>
{{ .Pre }}
<a href="{{ .URL }}">{{ .Name }}</a>
{{ template "treesub" . }}
</li>
{{ end }}
</ul>
{{ end }}
{{ end }}
That is, map the current page’s section to a menu of the same name, then traverse down that recursively to build a menu. It’s a file tree-based version of that which I’m after.
I suspect you can use Hugo’s nested sections for this. It requires a “_index.md” file in the lower-most folders, and then you can do something like this:
Problem 1: If I make the recursive template call to $element, I get a nice nested list but it seems to repeat numerous times. If I make it to ., sub-sections don’t get called at all. This one is probably just a dumb PEBCAK.
Problem 2: As written this gets me a tree of the entire content directory. That’s not what I’m looking for; I’m looking for a tree just for the branch of the site the current page is in.
As an example, if I have top level sections “plant”, “animal”, and “fungus”, and under animal I have “mammals”, “reptiles”, and “birds”, when I’m on the “cat” page I want to see “mammals”, “reptiles”, and “birds” as the top items in the menu that’s generated. I’m not clear how to trim it down like that.
The way I am doing a Conditional Section Menu is by displaying Hugo Menu Items based on a conditional check of the Menu Item .URL vs the Page .Type (Note: .Type is an alias of .Section).
So provided that you have configured a standard Hugo Menu for your Section and Nested Sections called .Menus.section (look into the Docs for Menu configuration -I’m not going into the specifics-)
You can do the following:
{{ range .Site.Menus.section }}
{{ if (strings.Contains .URL $.Type) }}
<a href="{{ .URL }}">{{ .Name }}</a>
{{ end }}
{{ end }}
Sure. You can adapt it to start at “.CurrentSection”. Sorry, but I cannot get into specific troubleshooting with you on this … prose level. My post was meant to give you a direction, not a ready-to-use solution.