Menu Configuration
Relevant source files
The following files were used as context for generating this wiki page:The documentation site, built with Hugo, utilizes a flexible menu configuration system to generate its navigation structures. This system relies on YAML configuration files located in config/_default/menus/ to define the menu hierarchy. There are two primary menus: the main navigation menu (main.en.yaml) for general documentation, and a specialized API menu (api.en.yaml) for the API reference section.
While the main menu is manually curated, the API menu is dynamically generated by Node.js scripts that parse OpenAPI specification files. This hybrid approach allows for both structured, hand-crafted navigation for documentation and automated, up-to-date navigation for the extensive API reference. The Hugo templating engine, specifically layouts/partials/nav/left-nav.html and layouts/api/list.html, consumes these configurations to render the final HTML navigation elements.
Menu Architecture Overview
The site's navigation is primarily driven by two separate menu configurations, which are processed by Hugo's templating engine to generate the user-facing navigation panels.
This diagram illustrates the flow from YAML configuration files through the Hugo build process to the final rendered HTML navigation components.
Sources: layouts/partials/nav/left-nav.html, layouts/api/list.html, config/_default/menus/main.en.yaml, config/_default/menus/api.en.yaml
Main Navigation
The main navigation, rendered on the left side of most documentation pages, is defined in config/_default/menus/main.en.yaml. This file contains a hierarchical structure of menu items.
Sources: config/_default/menus/main.en.yaml, layouts/partials/nav/left-nav.html
Structure and Properties
Each entry in main.en.yaml represents a link in the navigation and can have several properties. The menu supports a nested structure with up to four levels of depth.
| Property | Type | Description |
|---|---|---|
name | String | The display text for the menu item. |
identifier | String | A unique ID for the menu item, used for referencing and styling. |
url | String | The relative URL path for the link. |
parent | String | The identifier of the parent menu item, used to create nested menus. |
pre | String | An icon name to be displayed before the menu item text. |
weight | Integer | A number that determines the sorting order of items at the same level (not explicitly used in main.en.yaml but is a standard Hugo property). |
Sources: config/_default/menus/main.en.yaml, layouts/partials/nav/left-nav.html:18-29
Rendering Logic
The layouts/partials/nav/left-nav.html template is responsible for rendering the main navigation. It recursively iterates through the main menu object provided by Hugo.
- It starts by iterating through the top-level menu items.
- For each item, it creates a
<li>element with a link<a>. - If an item has children (
.HasChildren), it creates a nested<ul>and recursively renders the child items. - The template supports up to four levels of nesting.
- The
data-pathattribute on each link is constructed from the item's URL, which is used by client-side scripts.
{{/* layouts/partials/nav/left-nav.html - Simplified rendering logic */}}
{{ range .Site.Menus.main }}
{{ if .HasChildren }}
<p class="h5 text-uppercase fw-bold">{{.Name}}</p>
<ul class="list-unstyled">
{{ range .Children }} {{/* LEVEL 1 */}}
<li class="nav-top-level ...">
<a href="{{ .URL | relLangURL }}" ...>
<span>{{ .Name }}</span>
</a>
<ul class="list-unstyled sub-menu ...">
{{ range .Children }} {{/* LEVEL 2 */}}
...
{{ if .HasChildren }}
<ul class="list-unstyled sub-menu ...">
{{ range .Children }} {{/* LEVEL 3 */}}
...
{{ if .HasChildren }}
<ul class="list-unstyled sub-menu ...">
{{ range .Children }} {{/* LEVEL 4 */}}
...
{{ end }}
</ul>
{{ end }}
{{ end }}
</ul>
{{ end }}
{{ end }}
</ul>
</li>
{{ end }}
</ul>
{{ end }}
{{ end }}
Sources: layouts/partials/nav/left-nav.html:18-103
API Navigation
The API reference section uses a separate menu defined in config/_default/menus/api.en.yaml. This menu is partially handwritten and partially auto-generated from OpenAPI specifications.
Sources: config/_default/menus/api.en.yaml, assets/scripts/build-api-pages.js, assets/scripts/build-reference-pages.js
Structure and Properties
The api.en.yaml file follows a similar structure to the main menu but includes additional custom parameters used by the API page templates.
| Property | Type | Description |
|---|---|---|
name | String | The display text for the menu item. For endpoints, this is the summary from the OpenAPI spec. |
url | String | The URL. For top-level tags, it points to the section page. For endpoints, it's an anchor link (#...). |
identifier | String | A unique ID for the menu item. |
parent | String | The identifier of the parent tag, linking an endpoint to its category. |
generated | Boolean | A flag indicating if the menu item was auto-generated by a script. This is used to preserve manual entries during regeneration. |
params | Object | A map of custom parameters passed to the template. |
params.versions | Array | An array of API versions (e.g., ["v1", "v2"]) where the endpoint is available. |
params.operationids | Array | An array of operationId strings from the OpenAPI spec corresponding to this menu item. |
params.unstable | Array | An array of API versions where the endpoint is marked as unstable. |
params.order | Integer | A custom ordering value derived from x-menu-order in the OpenAPI spec. |
Sources: config/_default/menus/api.en.yaml, assets/scripts/build-api-pages.js:63-75, assets/scripts/build-reference-pages.js:63-75
Automated Menu Generation
The assets/scripts/build-api-pages.js and assets/scripts/build-reference-pages.js scripts contain an updateMenu function that populates the api.en.yaml file. This process ensures the API navigation stays in sync with the OpenAPI specifications.
The generation process is as follows:
- The script reads the existing
api.en.yamlfile. - It removes all entries marked with
generated: trueto start fresh while preserving any manually added items. - It processes an array of OpenAPI specification files (e.g., for v1 and v2).
- For each spec, it iterates through
tags, which become top-level parent menu items. - It then iterates through all
pathsand their associated HTTP methods (actions). - For each action, it creates a child menu item under the corresponding tag. It populates the
namefrom the action'ssummaryand sets theparentto the tag's identifier. - Crucially, it populates the
paramsobject with metadata like APIversions,operationids, andunstablestatus, which is essential for the rendering logic on the API pages. - The newly constructed menu array is written back to
config/_default/menus/api.en.yaml.
This flowchart shows the process of generating the API menu from OpenAPI specifications.
Sources: assets/scripts/build-api-pages.js:19-100, assets/scripts/build-reference-pages.js:19-100
API Menu Consumption
The layouts/api/list.html template uses the generated api menu to construct the content of each API section page.
The rendering flow is as follows:
- The template identifies the current API section based on the page's title (e.g., "Monitors").
- It finds the corresponding top-level entry in the
apimenu. - It then iterates through the children of that menu item, which represent the individual API endpoints.
- For each endpoint, it uses the
params(especiallyoperationidsandversions) stored in the menu item to fetch the detailed endpoint data from the full, dereferenced OpenAPI specification loaded into Hugo's data context. - This data is then used to render the endpoint's documentation, including its URL, description, parameters, request body, responses, and code examples.
This sequence diagram shows how the API list template uses the api menu to dynamically build the page content from OpenAPI spec data.
Sources: layouts/api/list.html:48-70