mirror of https://github.com/docker/docs.git
hugo: render site navigation using sections
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
This commit is contained in:
parent
135870fc13
commit
c36309ed8a
|
@ -24,9 +24,12 @@ The website is built using [Hugo](https://gohugo.io/). The content is primarily
|
||||||
Markdown files in the `/content` directory of this repository (with a few
|
Markdown files in the `/content` directory of this repository (with a few
|
||||||
exceptions, see [Content not edited here](#content-not-edited-here)).
|
exceptions, see [Content not edited here](#content-not-edited-here)).
|
||||||
|
|
||||||
The structure of the sidebar navigation on the site is defined in
|
The structure of the sidebar navigation on the site is defined by the site's
|
||||||
[`/data/toc.yaml`](./data/toc.yaml). To rename or change the location of a page
|
section hierarchy in the `contents` directory. The titles of the pages are
|
||||||
in the left-hand navigation, edit the `toc.yaml` file.
|
defined in the front matter of the Markdown files. You can use `title` and
|
||||||
|
`linkTitle` to define the title of the page. `title` is used for the page
|
||||||
|
title, and `linkTitle` is used for the sidebar title. If `linkTitle` is not
|
||||||
|
defined, the `title` is used for both.
|
||||||
|
|
||||||
You must fork this repository to create a pull request to propose changes. For more details, see [Local setup](#local-setup).
|
You must fork this repository to create a pull request to propose changes. For more details, see [Local setup](#local-setup).
|
||||||
|
|
||||||
|
|
|
@ -31,14 +31,6 @@
|
||||||
@apply dark:hue-rotate-180 dark:invert dark:filter;
|
@apply dark:hue-rotate-180 dark:invert dark:filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-hover {
|
|
||||||
@apply hover:bg-gray-light-200 hover:dark:bg-gray-dark-200;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-underline {
|
|
||||||
@apply underline decoration-blue-light decoration-4 underline-offset-4 dark:decoration-blue-dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-pattern-blue {
|
.bg-pattern-blue {
|
||||||
background-color: theme(colors.white / 50%);
|
background-color: theme(colors.white / 50%);
|
||||||
background-image: url('/assets/images/bg-pattern-blue.webp');
|
background-image: url('/assets/images/bg-pattern-blue.webp');
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
function toggleMenuItem(event) {
|
|
||||||
const section = event.currentTarget.parentElement;
|
|
||||||
const icons = event.currentTarget.querySelectorAll(".icon-svg");
|
|
||||||
const subsection = section.querySelector("ul");
|
|
||||||
subsection.classList.toggle("hidden");
|
|
||||||
icons.forEach(i => i.classList.toggle('hidden'))
|
|
||||||
}
|
|
||||||
|
|
||||||
const sectiontree = document.querySelector("#sectiontree");
|
|
||||||
if (sectiontree) {
|
|
||||||
for (const button of sectiontree.querySelectorAll("button")) {
|
|
||||||
button.addEventListener("click", toggleMenuItem);
|
|
||||||
}
|
|
||||||
}
|
|
2441
data/toc.yaml
2441
data/toc.yaml
File diff suppressed because it is too large
Load Diff
10
hugo.yaml
10
hugo.yaml
|
@ -120,19 +120,19 @@ params:
|
||||||
menus:
|
menus:
|
||||||
main:
|
main:
|
||||||
- name: Get started
|
- name: Get started
|
||||||
url: /get-started/
|
pageRef: /get-started/
|
||||||
weight: 1
|
weight: 1
|
||||||
- name: Guides
|
- name: Guides
|
||||||
url: /guides/
|
pageRef: /guides/
|
||||||
weight: 2
|
weight: 2
|
||||||
- name: Manuals
|
- name: Manuals
|
||||||
url: /manuals/
|
pageRef: /manuals/
|
||||||
weight: 3
|
weight: 3
|
||||||
- name: Reference
|
- name: Reference
|
||||||
url: /reference/
|
pageRef: /reference/
|
||||||
weight: 4
|
weight: 4
|
||||||
- name: Learning paths
|
- name: Learning paths
|
||||||
url: /learning-paths/
|
pageRef: /learning-paths/
|
||||||
weight: 5
|
weight: 5
|
||||||
|
|
||||||
footer:
|
footer:
|
||||||
|
|
|
@ -307,12 +307,16 @@
|
||||||
"highlight",
|
"highlight",
|
||||||
"hover:bg-blue-light-400",
|
"hover:bg-blue-light-400",
|
||||||
"hover:bg-gray-light-100",
|
"hover:bg-gray-light-100",
|
||||||
|
"hover:bg-gray-light-300",
|
||||||
"hover:border-gray-light-200",
|
"hover:border-gray-light-200",
|
||||||
|
"hover:dark:bg-gray-dark-300",
|
||||||
"hover:dark:border-gray-dark",
|
"hover:dark:border-gray-dark",
|
||||||
|
"hover:dark:text-blue-dark",
|
||||||
"hover:drop-shadow-lg",
|
"hover:drop-shadow-lg",
|
||||||
"hover:opacity-75",
|
"hover:opacity-75",
|
||||||
"hover:opacity-90",
|
"hover:opacity-90",
|
||||||
"hover:text-black",
|
"hover:text-black",
|
||||||
|
"hover:text-blue-light",
|
||||||
"hover:underline",
|
"hover:underline",
|
||||||
"hub-api",
|
"hub-api",
|
||||||
"icon-lg",
|
"icon-lg",
|
||||||
|
@ -451,9 +455,9 @@
|
||||||
"scale-75",
|
"scale-75",
|
||||||
"scroll-mt-20",
|
"scroll-mt-20",
|
||||||
"scroll-mt-36",
|
"scroll-mt-36",
|
||||||
|
"select-none",
|
||||||
"self-center",
|
"self-center",
|
||||||
"shadow",
|
"shadow",
|
||||||
"sidebar-hover",
|
|
||||||
"sm:flex-row",
|
"sm:flex-row",
|
||||||
"sm:grid-cols-2",
|
"sm:grid-cols-2",
|
||||||
"sm:items-center",
|
"sm:items-center",
|
||||||
|
|
|
@ -1,18 +1,7 @@
|
||||||
{{ $scratch := partialCached "utils/tocparser.html" . . }}
|
|
||||||
{{ $ctx := . }}
|
|
||||||
|
|
||||||
|
|
||||||
<nav id="breadcrumbs" data-pagefind-ignore class="py-4 gap-4 flex items-center text-gray-light dark:text-gray-dark max-w-full min-w-0">
|
<nav id="breadcrumbs" data-pagefind-ignore class="py-4 gap-4 flex items-center text-gray-light dark:text-gray-dark max-w-full min-w-0">
|
||||||
{{ with ($scratch.GetSortedMapValues "sections") }}
|
{{ range .Ancestors.Reverse }}
|
||||||
{{ range $i, $e := . }}
|
<a href="{{ .Permalink }}" class="link truncate">{{ markdownify .LinkTitle }}</a>
|
||||||
{{- if $i -}}
|
|
||||||
<span>/</span>
|
<span>/</span>
|
||||||
{{- end -}}
|
{{- end }}
|
||||||
<a href="{{ $e.path }}" class="link truncate">{{ markdownify $e.title }}</a>
|
<span class="truncate">{{ markdownify .LinkTitle }}</span>
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- with $scratch.Get "lastsection" -}}
|
|
||||||
<span>/</span>
|
|
||||||
<span class="truncate">{{ markdownify .title }}</span>
|
|
||||||
{{- end -}}
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -1,74 +1,78 @@
|
||||||
{{/* Parse toc.yaml and store the resulting map to $scratch */}}
|
|
||||||
{{ $scratch := partialCached "utils/tocparser.html" . . }}
|
|
||||||
{{ $ctx := . }}
|
|
||||||
|
|
||||||
{{/* Get the name of the first section */}}
|
|
||||||
{{ $firstSection := (index ($scratch.GetSortedMapValues "sections") 0).title }}
|
|
||||||
|
|
||||||
{{/* Render the top-nav in sidebar for small screens */}}
|
{{/* Render the top-nav in sidebar for small screens */}}
|
||||||
<nav class="text-sm pb-4 gap-4 flex md:hidden flex-col justify-evenly">
|
<nav class="text-sm pb-4 gap-4 flex md:hidden flex-col justify-evenly">
|
||||||
<div class="text-gray-light dark:text-gray-dark">Main sections</div>
|
<div class="text-gray-light dark:text-gray-dark">Main sections</div>
|
||||||
{{ range site.Menus.main }}
|
{{ range site.Menus.main }}
|
||||||
<div class="pl-2 underline-offset-8 decoration-2 hover:underline decoration-blue-light dark:decoration-blue-dark hover:opacity-75
|
<div class="pl-2 underline-offset-8 decoration-2 hover:underline decoration-blue-light dark:decoration-blue-dark hover:opacity-75
|
||||||
{{- if eq $firstSection .Name }}
|
{{- if or (page.IsDescendant .Page) (eq page .Page) }}
|
||||||
underline
|
underline
|
||||||
{{- end }}">
|
{{- end }}">
|
||||||
<a href="{{ .URL }}">{{ .Name }}</a>
|
<a href="{{ .URL }}">{{ .Name }}</a>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</nav>
|
</nav>
|
||||||
{{ if $firstSection }}
|
<nav class="text-sm flex flex-col">
|
||||||
{{ $allSections := slice }}
|
|
||||||
{{ range $i, $e := ($scratch.GetSortedMapValues "sections") }}
|
|
||||||
{{ $allSections = $allSections | append (index $e "title") }}
|
|
||||||
{{ end }}
|
|
||||||
<nav id="sectiontree" class="text-sm flex flex-col">
|
|
||||||
<div class="block py-4 md:hidden text-gray-light dark:text-gray-dark">This section</div>
|
<div class="block py-4 md:hidden text-gray-light dark:text-gray-dark">This section</div>
|
||||||
{{/* The current page is in the table of contents */}}
|
{{/* The current page is in the table of contents */}}
|
||||||
<ul>
|
<ul>
|
||||||
{{/* Walk the toc.yaml nodes under the current main section */}}
|
{{ template "renderSingle" .FirstSection }}
|
||||||
{{ range (index site.Data.toc $firstSection) }}
|
{{ template "renderChildren" .FirstSection }}
|
||||||
{{ template "tocRender" (dict "ctx" $ctx "entry" . "sections" $allSections) }}
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
{{ define "renderChildren" }}
|
||||||
|
{{- range .Pages }}
|
||||||
|
{{- if eq .Params.sitemap false }}
|
||||||
|
{{- continue }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .IsSection }}
|
||||||
|
{{- template "renderList" . }}
|
||||||
|
{{- else }}
|
||||||
|
{{- template "renderSingle" . }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{/* Recursive template for sidebar items */}}
|
{{/* Recursive template for sidebar items */}}
|
||||||
{{ define "tocRender" }}
|
{{ define "renderList" }}
|
||||||
{{ $ctx := .ctx }}
|
{{ $isCurrent := eq page . }}
|
||||||
{{ $sections := .sections }}
|
{{ $expanded := or $isCurrent (page.IsDescendant .) }}
|
||||||
{{ if .entry.sectiontitle }}
|
<li x-data="{ expanded: {{$expanded}} }">
|
||||||
{{ $expanded := in $sections .entry.sectiontitle }}
|
<div class="rounded px-4 w-full flex items-center justify-between{{ if $isCurrent }} bg-gray-light-200 dark:bg-gray-dark-200{{ end }}">
|
||||||
{{/* .entry is a section */}}
|
|
||||||
<li>
|
|
||||||
{{/* See event handler in assets/js/src/sidebar.js */}}
|
|
||||||
<button class="rounded px-4 sidebar-hover w-full flex items-center justify-between">
|
|
||||||
<span class="py-2 truncate flex items-center gap-2">
|
<span class="py-2 truncate flex items-center gap-2">
|
||||||
{{ markdownify .entry.sectiontitle }}
|
{{- if .Permalink }}
|
||||||
|
{{/* If the link is not empty, use it */}}
|
||||||
|
<a class="select-none hover:text-blue-light hover:dark:text-blue-dark"
|
||||||
|
href="{{ .Permalink }}">{{ markdownify .LinkTitle }}</a>
|
||||||
|
{{- else }}
|
||||||
|
{{/* Otherwise, just expand the section */}}
|
||||||
|
<button @click="expanded = !expanded"
|
||||||
|
class="select-none hover:text-blue-light hover:dark:text-blue-dark">
|
||||||
|
{{ markdownify .LinkTitle }}
|
||||||
|
</button>
|
||||||
|
{{- end }}
|
||||||
</span>
|
</span>
|
||||||
<span class="icon-svg {{ if $expanded }}hidden{{ end }}">
|
<button @click="expanded = !expanded" class="hover:bg-gray-light-300 hover:dark:bg-gray-dark-300 rounded">
|
||||||
|
<span :class="{ 'hidden' : expanded }" class="icon-svg {{ if $expanded }}hidden{{ end }}">
|
||||||
{{ partialCached "icon" "expand_more" "expand_more" }}
|
{{ partialCached "icon" "expand_more" "expand_more" }}
|
||||||
</span>
|
</span>
|
||||||
<span class="icon-svg {{ if not $expanded }}hidden{{ end }}">
|
<span :class="{ 'hidden' : !expanded }" class="icon-svg {{ if not $expanded }}hidden{{ end }}">
|
||||||
{{ partialCached "icon" "expand_less" "expand_less" }}
|
{{ partialCached "icon" "expand_less" "expand_less" }}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="{{if not $expanded}}hidden {{end}}ml-3">
|
</div>
|
||||||
{{ range .entry.section }}
|
<ul :class="{ 'hidden' : !expanded }" class="{{if not $expanded}}hidden {{end}}ml-3">
|
||||||
{{ template "tocRender" (dict "entry" . "ctx" $ctx "sections" $sections ) }}
|
{{ template "renderChildren" . }}
|
||||||
{{ end }}
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
{{ else }}
|
{{ end }}
|
||||||
{{/* .entry is a page */}}
|
|
||||||
{{ $isCurrent := eq (urls.Parse $ctx.Permalink).Path .entry.path }}
|
{{ define "renderSingle" }}
|
||||||
<li class="pl-4 sidebar-hover rounded
|
{{ $isCurrent := eq page . }}
|
||||||
|
<li class="pl-4 hover:text-blue-light hover:dark:text-blue-dark
|
||||||
{{ if $isCurrent }} bg-gray-light-200 dark:bg-gray-dark-200{{ end }}">
|
{{ if $isCurrent }} bg-gray-light-200 dark:bg-gray-dark-200{{ end }}">
|
||||||
<a {{ if $isCurrent }}aria-current="page" {{ end }} class="py-2 w-full truncate block"
|
<a {{ if $isCurrent }}aria-current="page" {{ end }} class="py-2 w-full truncate block"
|
||||||
href="{{ .entry.path }}" title="{{ markdownify .entry.title }}"
|
href="{{ .Permalink }}" title="{{ markdownify .Title }}"
|
||||||
><span class="flex items-center gap-2">{{ markdownify .entry.title }}</span>
|
><span class="flex items-center gap-2">{{ markdownify .LinkTitle }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
{{ $scratch := partialCached "utils/tocparser.html" . . }}
|
|
||||||
{{ $firstSection := (index ($scratch.GetSortedMapValues "sections") 0).title }}
|
|
||||||
<div>
|
<div>
|
||||||
<nav>
|
<nav>
|
||||||
<ul class="mt-1 box-content hidden gap-4 md:flex">
|
<ul class="mt-1 box-content hidden gap-4 md:flex">
|
||||||
{{ range site.Menus.main }}
|
{{ range site.Menus.main }}
|
||||||
<li {{- if or (eq $firstSection .Name) }} class="border-b-4" {{- end }}>
|
<li {{- if or (eq page .Page) (page.IsDescendant .Page) }} class="border-b-4" {{- end }}>
|
||||||
<a class="block px-2 py-1" href="{{ .URL }}">{{ .Name }}</a>
|
<a class="block px-2 py-1" href="{{ .URL }}">{{ .Name }}</a>
|
||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
{{ $ctx := . }}
|
|
||||||
{{ $scratch := newScratch }}
|
|
||||||
{{ $toc := site.Data.toc }}
|
|
||||||
{{ range $root, $section := $toc }}
|
|
||||||
{{ if ne ($scratch.Get "match") true }}
|
|
||||||
{{ $scratch.Set "depth" 1 }}
|
|
||||||
{{ $rootSectionLink := "" }}
|
|
||||||
{{ with (index $section 0) }}
|
|
||||||
{{ if .path }}
|
|
||||||
{{ $rootSectionLink = .path }}
|
|
||||||
{{ else }}
|
|
||||||
{{ $rootSectionLink = (index .section 0).path }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
{{ $scratch.SetInMap "sections" "1" (dict "title" $root "path" $rootSectionLink) }}
|
|
||||||
{{ template "tocWalk" (dict "scratch" $scratch "section" $section "ctx" $ctx) }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ define "tocWalk" }}
|
|
||||||
{{ $ctx := .ctx }}
|
|
||||||
{{ $scratch := .scratch }}
|
|
||||||
{{ $scratch.Set "depth" (add ($scratch.Get "depth") 1) }}
|
|
||||||
{{ range .section }}
|
|
||||||
{{ if ne ($scratch.Get "match") true }}
|
|
||||||
{{ if .path }}
|
|
||||||
{{ $match := eq (urls.Parse .path).Path (urls.Parse $ctx.Permalink).Path }}
|
|
||||||
{{ if $match }}
|
|
||||||
{{ $scratch.Set "match" true }}
|
|
||||||
{{ $scratch.Set "maxdepth" ($scratch.Get "depth") }}
|
|
||||||
{{ $scratch.Set "lastsection" (dict "title" .title "path" .path) }}
|
|
||||||
{{ end }}
|
|
||||||
{{ else }}
|
|
||||||
{{ $sectionLink := (index .section 0).path }}
|
|
||||||
{{ $scratch.SetInMap "sections" (string ($scratch.Get "depth")) (dict "title" .sectiontitle "path" $sectionLink) }}
|
|
||||||
{{ template "tocWalk" (dict "scratch" $scratch "section" .section "ctx" $ctx) }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
{{ $scratch.Set "depth" (sub ($scratch.Get "depth") 1) }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ range $depth, $e := ($scratch.Get "sections") }}
|
|
||||||
{{ if ge $depth ($scratch.Get "maxdepth") }}
|
|
||||||
{{ $scratch.DeleteInMap "sections" $depth }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ return $scratch }}
|
|
|
@ -20,8 +20,6 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{ range .Paginator.Pages }}
|
{{ range .Paginator.Pages }}
|
||||||
{{ $scratch := partialCached "utils/tocparser.html" . . }}
|
|
||||||
{{ $sections := $scratch.GetSortedMapValues "sections" }}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ .Permalink }}" class="link">
|
<a href="{{ .Permalink }}" class="link">
|
||||||
|
@ -30,10 +28,9 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="text-gray-light dark:text-gray-dark">
|
<span class="text-gray-light dark:text-gray-dark">
|
||||||
{{ range $i, $e := $sections }}
|
{{- range .Ancestors.Reverse }}
|
||||||
{{ if $i }} / {{ end }}
|
{{ .Title }} /
|
||||||
{{ $e.title }}
|
{{- end }}
|
||||||
{{ end }}
|
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
Loading…
Reference in New Issue