Customizing Page Layouts
Relevant source files
The following files were used as context for generating this wiki page:
This document provides a technical overview of the page layout and rendering system used in the Docker documentation project. The project leverages the Hugo static site generator, which uses a system of layouts, templates, and partials to transform Markdown content into final HTML pages. Understanding this system is key to customizing the appearance and structure of different page types.
The core of the layout system resides in the layouts/ directory. Hugo follows a specific lookup order to determine which template to use for a given piece of content, allowing for default layouts that can be overridden by more specific ones. Page-level configuration is managed via YAML front matter in each Markdown file, enabling fine-grained control over elements like the table of contents and sidebar behavior.
Hugo Configuration for Layouts
The primary configuration file, hugo.yaml, defines global settings that influence how pages are built and structured. Key sections related to page layout include permalinks, markup, and outputs.
Sources: hugo.yaml
Permalinks
The permalinks configuration controls the URL structure for content. A notable rule is defined for the manuals section, which removes the /manuals prefix from the published URL.
| Content Path | Published URL Path |
|---|---|
content/manuals/docker-desktop/ | /docker-desktop/ |
content/manuals/engine/extend/ | /engine/extend/ |
This behavior is configured as follows:
# hugo.yaml:11-16
permalinks:
page:
manuals: /:sections[1:]/:slugorcontentbasename/
section:
manuals: /:sections[1:]/
Sources: hugo.yaml:11-16
Markup and Table of Contents
The markup.tableOfContents settings in hugo.yaml establish the default heading levels to be included in the in-page Table of Contents (TOC). By default, it includes <h2> (level 2) through <h3> (level 3) headings.
# hugo.yaml:18-21
markup:
tableOfContents:
startLevel: 2
endLevel: 3
These defaults can be overridden on a per-page basis using front matter, as described in the Front Matter Controls section.
Sources: hugo.yaml:18-21
Layout Lookup Order
Hugo uses a defined lookup order to find the appropriate layout file for rendering a content page. It first looks for a layout in a directory matching the content's section, and if not found, falls back to the _default directory. This allows for creating specialized layouts for sections like guides or reference while maintaining a consistent default.
The diagram below illustrates the lookup process for a single page.
This diagram shows how Hugo resolves the layout for a page in the guides section.
In this project, layouts/guides/single.html exists but simply delegates to the default implementation, demonstrating the fallback and inheritance pattern.
<!-- layouts/guides/single.html:1-3 -->
{{- define "main" -}}
{{- partial "main.html" . -}}
{{- end -}}
This shows that the guides section uses the default main.html partial for its main content block, allowing for future customization without breaking the existing structure.
Sources: layouts/guides/single.html:1-3, layouts/_default/
Front Matter Controls
Page-specific layout and behavior can be controlled using YAML front matter at the top of each Markdown file. These settings can override the global defaults defined in hugo.yaml.
The following table summarizes key front matter keys that influence page layout:
| Key | Description |
|---|---|
title | The <h1> page title. |
notoc | If true, the in-page TOC is not generated for the page. |
toc_min | Overrides the minimum heading level for the TOC (default is 2). |
toc_max | Overrides the maximum heading level for the TOC (default is 3). |
sidebar.goto | Changes the sidebar link for this entry to point to a different URL. |
sidebar.badge | Adds a colored text badge to the sidebar entry for this page. |
Sources: content/contribute/file-conventions.md:17-43
For example, to create a page without a TOC and with a custom sidebar link, the front matter would look like this:
---
title: My Pageless Entry
notoc: true
sidebar:
goto: /some/other/page/
---
Sources: content/contribute/file-conventions.md:29, content/contribute/file-conventions.md:39-40
Partials and Dynamic Content
Partials are reusable template snippets located in layouts/partials/. They are used to inject dynamic or complex content into pages, such as structured data for SEO.
Schema.org Structured Data
The layouts/partials/schema.html partial is responsible for generating JSON-LD structured data, which helps search engines understand the content of the page. It dynamically builds two main schema types: TechArticle and BreadcrumbList.
The following diagram illustrates the data flow for generating the TechArticle schema.
This sequence shows how schema.html gathers page data to build the JSON-LD output.
The partial uses Hugo's built-in variables and functions to populate the schema:
headline: Populated from the page's.LinkTitle.description: Populated using a custom description partial.datePublished/dateModified: Populated from Git info (.PublishDate,.Lastmod).author/publisher: Hardcoded as "Docker Inc".timeRequired: Parsed from thetimeparameter in the page's front matter (e.g., "30 minutes" is converted to "PT30M").
Sources: layouts/partials/schema.html:5-52
Similarly, it generates a BreadcrumbList schema by iterating through the page's ancestors (.Ancestors) to build a navigation path, which is also embedded in a <script type="application/ld+json"> tag.
Sources: layouts/partials/schema.html:55-83
Conclusion
Customizing page layouts in the Docker documentation is achieved through a combination of Hugo's templating system, global configuration, and page-specific front matter. The layouts directory provides the structural templates, with _default serving as a fallback. Global settings in hugo.yaml control site-wide behavior like URL structures. Finally, front matter within each Markdown file offers granular control over individual page features, and partials like schema.html enable the injection of complex, data-driven content for purposes like SEO. This layered approach provides both consistency and flexibility in rendering the documentation.