docs: support nested Hugo menus - first draft #423

This commit is contained in:
Sören Weber 2024-10-22 23:57:21 +02:00
parent 79b43fcfce
commit d6f35f44f6
No known key found for this signature in database
GPG key ID: BEC6D55545451B6D
12 changed files with 229 additions and 124 deletions

View file

@ -31,7 +31,7 @@ The Relearn theme is an enhanced fork of the popular [Learn theme](https://githu
- [Chapter and site-wide printing capabilities](https://mcshelby.github.io/hugo-theme-relearn/configuration/sitemanagement/outputformats#print-support)
- [Versatile search options: in-page, popup, and dedicated search page](https://mcshelby.github.io/hugo-theme-relearn/configuration/sidebar/search)
- [Customizable top bar buttons](https://mcshelby.github.io/hugo-theme-relearn/configuration/customization/topbar)
- [Nested menus](https://mcshelby.github.io/hugo-theme-relearn/authoring/frontmatter/navigationmenu)
- [Nested menus](https://mcshelby.github.io/hugo-theme-relearn/authoring/frontmatter/menu)
- [Configurable menus](https://mcshelby.github.io/hugo-theme-relearn/configuration/sidebar/shortcutmenu)
- [Support for hidden pages](https://mcshelby.github.io/hugo-theme-relearn/configuration/content/hidden)
- [Comprehensive taxonomy support](https://mcshelby.github.io/hugo-theme-relearn/configuration/customization/taxonomy)

View file

@ -196,6 +196,19 @@ additionalContentLanguage = [ 'en' ]
# Menu
# These options modify the menu appearance.
# Hide the Home entry.
# Default: false
# If shown, a Home button will appear below the search bar and the main menu.
# It links to your the home page of the current language.
disableLandingPageButton = true
# Hide the language switcher.
# Default: false
# If you have more than one language configured, a language switcher is
# displayed in the lower part of the menu. This option lets you explicitly
# turn this behavior off.
disableLanguageSwitchingButton = false
# Shows checkmarks for visited pages of the main menu.
# Default: false
# This also causes the display of the `Clear History` entry in the lower part
@ -203,12 +216,6 @@ additionalContentLanguage = [ 'en' ]
# if you regenerate your site as the ids are not stable.
showVisitedLinks = true
# Hide the Home entry.
# Default: false
# If shown, a Home button will appear below the search bar and the main menu.
# It links to your the home page of the current language.
disableLandingPageButton = true
# The order of main menu submenus.
# Default: 'weight'
# Submenus can be ordered by 'weight', 'title', 'linktitle', 'modifieddate',
@ -232,13 +239,6 @@ alwaysopen = ''
# This can be overridden in the page's frontmatter.
collapsibleMenu = true
# Hide the language switcher.
# Default: false
# If you have more than one language configured, a language switcher is
# displayed in the lower part of the menu. This option lets you explicitly
# turn this behavior off.
disableLanguageSwitchingButton = false
# Hide heading above the shortcuts menu.
# Default: false
# If a sidebar menu with identifier `shortcuts` is configured (see below),

View file

@ -0,0 +1,207 @@
+++
categories = ["howto"]
description = "Setting the behavior of the menus"
frontmatter = ["alwaysopen", "collapsibleMenu", "linkTitle", "menuPost", "menuPre", "ordersectionsby", "sidebarmenus"]
options = ["alwaysopen", "collapsibleMenu", "ordersectionsby", "sidebarmenus"]
title = "Menus"
weight = 2
+++
The theme can build menu trees from [the structure of your page files](authoring/structure) or from [Hugo's build in menu feature](https://gohugo.io/content-management/menus/).
- {{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} All configuration options in your `hugo.toml` apply to all menus but can be changed individually.
- {{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} In case of page structure menus, individual configuration is done via a page's front matter.
- {{% badge color="blueviolet" icon="bars" title=" " %}}Menu{{% /badge %}}. In case of Hugo menus, individual configuration is done via a menu entry's configuration.
## Expand State of Nested Sections
{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} {{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} You can change how submenus appear with `alwaysopen`.
{{% badge color="blueviolet" icon="bars" title=" " %}}Menu{{% /badge %}} For Hugo menus, you have to set `params.alwaysopen` instead.
If `alwaysopen=false` for any given entry, its children will not be shown in the menu as long as it is not necessary for the sake of navigation.
The theme generates the expand state based on the following rules:
- all parent entries of the active page including their [visible](authoring/meta#hidden) siblings are shown regardless of any settings
- immediate child entries of the active entry are shown regardless of any settings
- if not overridden, all other first level entries behave like they would have been given `alwaysopen=false`
- if not overridden, all other entries of levels besides the first behave like they would have been given `alwaysopen=true`
- all [visible](authoring/meta#hidden) entries show their immediate child entries if `alwaysopen=true`; this proceeds recursively
- all remaining entries are not shown
{{< multiconfig >}}
alwaysopen = false
{{< /multiconfig >}}
## Expander for Nested Sections
{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} {{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} Set `collapsibleMenu=true` to show submenus as collapsible trees with a clickable expander.
{{% badge color="blueviolet" icon="bars" title=" " %}}Menu{{% /badge %}} For Hugo menus, you have to set `params.collapsibleMenu=true` instead.
{{< multiconfig >}}
collapsibleMenu = true
{{< /multiconfig >}}
> [!WARNING]
> Using this option may cause degraded build performance by slowing down your build process.
>
> This is usually the case for menus with many entries and happens for page menus as well as for Hugo menus.
>
> We've seen builds taking 2 minutes with 1000+ pages, and over 30 minutes with 5000+ pages when using a page menu.
>
> This happens because each new page affects all other pages, leading to exponentially longer build times.
## Ordering Sibling Menu Entries
### By Weight
{{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} {{% badge color="blueviolet" icon="bars" title=" " %}}Menu{{% /badge %}} Hugo provides a [simple way](https://gohugo.io/getting-started/glossary/#weight) to handle order of your entries by setting the `weight` front matter to a number.
{{< multiconfig>}}
weight = 5
{{< /multiconfig >}}
### By Other
Using the `weight` for sorting can get cumbersome if you, for example, just want to sort alphabetically. Each time you add a new page in the set of pages, you may have to renumber some or all of them to make space for the new page.
{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} {{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} Use `ordersectionsby` to sort by other aspects. See the [children shortcode](shortcodes/children#parameter) for a complete list.
Hugo menus can only be sorted using the [weight method](#by-weight).
{{< multiconfig >}}
ordersectionsby = 'linktitle'
{{< /multiconfig >}}
## Title for Menu Entries
{{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} A page's `linkTitle` or `title` front matter will be used for naming a menu entry of a page menu, in that order if both are defined. Using `linkTitle` helps to shorten the text for menu entries if the pages title is too descriptive.
{{% badge color="blueviolet" icon="bars" title=" " %}}Menu{{% /badge %}} A menu entry's `title` or `name` will be used for naming a menu entry of a Hugo menu, in that order if both are defined.
For example for a page named `install/linux.md`
{{< multiconfig fm=true >}}
title = 'Install on Linux'
linkTitle = 'Linux'
{{< /multiconfig >}}
## Add Icon to a Menu Entry
{{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} For page menus, add a `menuPre` to insert any HTML code before the menu label. You can also set `menuPost` to insert HTML code after the menu label.
{{% badge color="blueviolet" icon="bars" title=" " %}}Menu{{% /badge %}} For Hugo menus, add a `pre` to insert any HTML code before the menu label. You can also set `post` to insert HTML code after the menu label.
The example below uses the GitHub icon for an entry of a page menu.
{{< multiconfig fm=true >}}
title = 'GitHub Repo'
menuPre = '<i class="fab fa-github"></i> '
{{< /multiconfig >}}
## Disable Parent Menu Entries
You may want to structure your entries in a hierarchical way but don't want to generate clickable parent entries? The theme got you covered.
### For Page Menus
To stay with the [initial example](authoring/structure): Suppose you want `first-chapter/first-page` appear in the sidebar but don't want to generate a page for it. So the entry in the sidebar should not be clickable but should show an expander.
For this, open `content/first-chapter/first-page/_index.md` and add the following front matter
{{< multiconfig fm=true >}}
[_build]
render = 'never'
{{< /multiconfig >}}
### For Hugo Menus
Just don't give your parent menu entry configuration a `url` or `pageRef`
{{< multiconfig fm=true >}}
[[menu.addendum]]
name = 'Parent'
[[menu.addendum]]
parent = 'Parent'
name = 'Child 1'
url = 'https://example.com/1'
weight = 1
[[menu.addendum]]
parent = 'Parent'
name = 'Child 2'
url = 'https://example.com/2'
weight = 2
{{< /multiconfig >}}
## Defining Menus
{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} {{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} Menus are defined using the `sidebarmenus` option.
You can define as many menus, as you like. If you don't overwrite this option, the theme defaults to
{{< multiconfig >}}
sidebarmenus = [
{ type = 'page', identifier = 'home', main = true, disableTitle = true, pageRef = '' },
{ type = 'menu', identifier = 'shortcuts', main = false, disableTitle = false },
]
{{< /multiconfig >}}
### Parameter
| Name | Default | Notes |
|-----------------------|-----------------|-------------|
| type | _&lt;empty&gt;_ | The type of menu.<br><br>- `page` for a page menu<br>- `menu` for a Hugo menu |
| identifier | _&lt;empty&gt;_ | A unique identifier for this entry<br><br>- for `type=page` an arbitrary name<br>- for `page=menu` the identifier of the menu definition in your `hugo.toml` |
| main | see notes | Whether to add additional spacing and larger text to the menu<br><br>- for `type=page` defaults to `true`<br>- for `page=menu` defaults to `false` |
| disableTitle | see notes | Whether to print a title above the menu<br><br>- for `type=page` defaults to `true`<br>- for `page=menu` defaults to `false` |
| pageRef | _&lt;empty&gt;_ | Only for `type=page`, the page path to start the menu tree. If not set, defaults to the home page. |
## Redefining Menus for Certain Pages
Suppose you are building a site that contains of a topmost `blog` and `documentation` section.
When the user is on one of the blog pages he should only see a menu containing all blog pages, while on a documentation page he should only see a menu containing all doc pages.
Directory structure:
````plaintext
content
├── blog
│ ├── post-1.md
│ ├── post-2.md
│ ├── post-3.md
│ └── _index_.md
├── docs
│ ├── topic-1.md
│ ├── topic-2.md
│ ├── topic-3.md
│ └── _index_.md
└── _index.md
````
{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} {{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} Using [Hugo's cascade feature](https://gohugo.io/content-management/front-matter/#cascade), we can redefine the menus once in `blog/_index.md` and `docs/_index.md` setting `sidebarmenus` so they will be used in all children pages.
{{< multiconfig fm=true file="blog/_index.md">}}
title = 'Blog'
[[cascade]]
[cascade.params]
sidebarmenus = [
{ type = 'page', identifier = 'blog', pageRef = '/blog' },
]
{{< /multiconfig >}}
{{< multiconfig fm=true file="docs/_index.md">}}
title = 'Documentation'
[[cascade]]
[cascade.params]
sidebarmenus = [
{ type = 'page', identifier = 'docs', pageRef = '/docs' },
]
{{< /multiconfig >}}

View file

@ -1,104 +0,0 @@
+++
categories = ["howto"]
description = "Behavior of the navigation menu"
frontmatter = ["alwaysopen", "collapsibleMenu", "linkTitle", "menuPost", "menuPre", "ordersectionsby"]
options = ["alwaysopen", "collapsibleMenu", "ordersectionsby"]
title = "Navigation Menu"
weight = 2
+++
The navigation menu is automatically created from [your content files](authoring/structure).
All configurations options apply to all pages but can be changed in each page's front matter.
## Expand State of Nested Sections
{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} {{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} You can change how the theme submenus appear with `alwaysopen`.
If `alwaysopen=false` for any given entry, its children will not be shown in the menu as long as it is not necessary for the sake of navigation.
The theme generates the expand state based on the following rules:
- all parent entries of the active page including their [visible](authoring/meta#hidden) siblings are shown regardless of any settings
- immediate child entries of the active page are shown regardless of any settings
- if not overridden, all other first level entries behave like they would have been given `alwaysopen=false`
- if not overridden, all other entries of levels besides the first behave like they would have been given `alwaysopen=true`
- all [visible](authoring/meta#hidden) entries show their immediate child entries if `alwaysopen=true`; this proceeds recursively
- all remaining entries are not shown
{{< multiconfig >}}
alwaysopen = false
{{< /multiconfig >}}
## Expander for Nested Sections
{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} {{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} Set `collapsibleMenu=true` to add an expander for submenus. This shows submenus as collapsible trees with a clickable expander.
{{< multiconfig >}}
collapsibleMenu = true
{{< /multiconfig >}}
> [!WARNING]
> Using this option may slow down your build process, especially with many pages.
>
> We've seen builds taking 2 minutes with 1000+ pages, and over 30 minutes with 5000+ pages.
>
> This happens because each new page affects all other pages, leading to exponentially longer build times.
## Ordering Sibling Menu Entries
### By Weight
Hugo provides a [simple way](https://gohugo.io/getting-started/glossary/#weight) to handle order for your pages by setting the `weight` front matter to a number.
{{< multiconfig fm=true >}}
title = 'My page'
weight = 5
{{< /multiconfig >}}
### By Other
{{% badge style="cyan" icon="gears" title=" " %}}Option{{% /badge %}} {{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} Using the `weight` for sorting can get cumbersome if you, for example, just want to sort alphabetically. Each time you add a new page in the set of pages, you may have to renumber some or all of them to make space for the new page.
{{< multiconfig >}}
ordersectionsby = 'linktitle'
{{< /multiconfig >}}
## Custom Title for Menu Entries
By default, the Relearn theme will use a page's `title` front matter for the menu entry.
{{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} But a page's title has to be descriptive on its own while the menu is a hierarchy. Use `linkTitle` to shorten the text of the menu entry.
For example for a page named `install/linux.md`
{{< multiconfig fm=true >}}
title = 'Install on Linux'
linkTitle = 'Linux'
{{< /multiconfig >}}
## Add Icon to a Menu Entry
{{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} In the page front matter, add a `menuPre` to insert any HTML code before the menu label. You can also set `menuPost` to insert HTML code after the menu label.
The example below uses the GitHub icon.
{{< multiconfig fm=true >}}
title = 'GitHub Repo'
menuPre = '<i class="fab fa-github"></i> '
{{< /multiconfig >}}
![Title with icon](item-with-icon.png?width=18.75rem)
## Disable Section Pages
You may want to structure your pages in a hierarchical way but don't want to generate pages for those sections? The theme got you covered.
To stay with the [initial example](authoring/structure): Suppose you want `first-chapter/first-page` appear in the sidebar but don't want to generate a page for it. So the entry in the sidebar should not be clickable but should show an expander.
For this, open `content/first-chapter/first-page/_index.md` and add the following front matter
{{< multiconfig fm=true >}}
[_build]
render = 'never'
{{< /multiconfig >}}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -38,6 +38,8 @@ images = [ 'images/hero.png' ]
{{% badge style="green" icon="fa-fw fab fa-markdown" title=" " %}}Front Matter{{% /badge %}} You can hide your pages from the menu by setting `hidden=true`.
{{% badge color="blueviolet" icon="bars" title=" " %}}Menu{{% /badge %}} For [Hugo menus](https://gohugo.io/content-management/menus/), you have to set `params.hidden=true` instead.
[See how you can further configure visibility](configuration/content/hidden) throughout your site.
{{< multiconfig fm=true >}}

View file

@ -24,7 +24,7 @@ weight = -0
### New
- {{% badge style="info" icon="plus-circle" title=" " %}}New{{% /badge %}} You can define the expansion state of your menus in the front matter. Please see further [documentation](authoring/frontmatter/navigationmenu#expand-state-of-nested-sections) for possible values and default behavior.
- {{% badge style="info" icon="plus-circle" title=" " %}}New{{% /badge %}} You can define the expansion state of your menus in the front matter. Please see further [documentation](authoring/frontmatter/menu#expand-state-of-nested-sections) for possible values and default behavior.
- {{% badge style="info" icon="plus-circle" title=" " %}}New{{% /badge %}} New partials for defining pre/post content for menu items and the content. See [documentation](configuration/customization/partials) for further reading.

View file

@ -16,7 +16,7 @@ weight = -4
- {{% badge style="info" icon="plus-circle" title=" " %}}New{{% /badge %}} Hidden pages are displayed by default in their according tags page. You can now turn off this behavior by setting `disableTagHiddenPages=true` in your `hugo.toml`.
- {{% badge style="info" icon="plus-circle" title=" " %}}New{{% /badge %}} You can define the expansion state of your menus for the whole site by setting the `alwaysopen` option in your `hugo.toml`. Please see further [documentation](authoring/frontmatter/navigationmenu#expand-state-of-nested-sections) for possible values and default behavior.
- {{% badge style="info" icon="plus-circle" title=" " %}}New{{% /badge %}} You can define the expansion state of your menus for the whole site by setting the `alwaysopen` option in your `hugo.toml`. Please see further [documentation](authoring/frontmatter/menu#expand-state-of-nested-sections) for possible values and default behavior.
- {{% badge style="info" icon="plus-circle" title=" " %}}New{{% /badge %}} New front matter `ordersectionsby` option to change immediate children sorting in menu and `children` shortcode. Possible values are `title` or `weight`.

View file

@ -16,7 +16,7 @@ weight = -22
- {{% badge style="note" title=" " %}}Change{{% /badge %}} You can now have structural sections in the hierarchical menu without generating a page for it.
This can come in handy, if content for such a section page doesn't make much sense to you. See [the documentation](authoring/frontmatter/navigationmenu#disable-section-pages) for how to do this.
This can come in handy, if content for such a section page doesn't make much sense to you. See [the documentation](authoring/frontmatter/menu#disable-parent-menu-entries) for how to do this.
This feature may require you to make changes to your existing installation if you are already using _[shortcuts to pages inside of your project](configuration/sidebar/shortcutmenu#displaying-pages-only-in-the-shortcuts-menu)_ with a _headless branch parent_.

View file

@ -19,7 +19,7 @@ weight = -0
- suffered from poor build performance for sites with 1000 or more pages
- reinvented the wheel instead of using available Hugo mechanisms
_What do I gain_, you may ask. A significant performance boost during build! Usually, the build time has been cut at least in half for bigger sites. It is now possible to build even larger sites with 5000 or more pages. This was previously almost impossible due to rapidly increasing build time with the more pages you've introduced. For even bigger sites, the theme now has [configurable performance optimizations](authoring/frontmatter/navigationmenu#expander-for-nested-sections) - at the price of feature limitations.
_What do I gain_, you may ask. A significant performance boost during build! Usually, the build time has been cut at least in half for bigger sites. It is now possible to build even larger sites with 5000 or more pages. This was previously almost impossible due to rapidly increasing build time with the more pages you've introduced. For even bigger sites, the theme now has [configurable performance optimizations](authoring/frontmatter/menu#expander-for-nested-sections) - at the price of feature limitations.
If you haven't done customizations to any partials, you can update right away.
@ -90,7 +90,7 @@ weight = -0
Also, a lot of previously undocumented features are now included, namely
- the [hidden pages](configuration/content/hidden) feature
- options of the [navigation menu](authoring/frontmatter/navigationmenu)
- options of the [navigation menu](authoring/frontmatter/menu)
- configuring [breadcrumb, titles](configuration/content/titles) and [headings](configuration/content/headings) of your content
- [options for using links](configuration/content/linking)
- adding [custom output formats](configuration/customization/outputformats)

View file

@ -1 +1 @@
7.0.1+06e70da8a6fb2043fe7e56b818ff638a309c8239
7.0.1+79b43fcfce316113e7e887422d7fda38ba9baa19