feat: add link button to toggle TOC items

This commit is contained in:
Mark Dumay
2025-08-15 09:52:20 +02:00
parent 3332b437dd
commit a57e0da164
8 changed files with 171 additions and 152 deletions

13
assets/js/toc.js Normal file
View File

@@ -0,0 +1,13 @@
const btnTOCShowMore = document.getElementById('btnTOCShowMore')
if (btnTOCShowMore !== null) {
btnTOCShowMore.addEventListener('click', (e) => {
btnTOCShowMore.style.display = 'none'
})
}
const btnTOCShowLess = document.getElementById('btnTOCShowLess')
if ((btnTOCShowLess !== null) && (btnTOCShowMore !== null)) {
btnTOCShowLess.addEventListener('click', (e) => {
btnTOCShowMore.style.display = 'initial'
})
}

View File

@@ -74,6 +74,14 @@
} }
} }
.btn-link.toc-item {
font-size: inherit;
}
#btnTOCShowMore {
padding-top: 0.875rem;
}
a.toc-item { a.toc-item {
display: block; display: block;
} }

View File

@@ -97,6 +97,9 @@
toc = true toc = true
sidebar = true sidebar = true
size = "md" size = "md"
startLevel = 2
endLevel = 3
maxNumHeadings = 9
[navigation.padding] [navigation.padding]
x = 4 x = 4
y = 4 y = 4

View File

@@ -51,6 +51,9 @@
toc = true toc = true
sidebar = true sidebar = true
size = "md" size = "md"
startLevel = 2
endLevel = 3
maxNumHeadings = 9
[navigation.padding] [navigation.padding]
x = 4 x = 4
y = 4 y = 4

View File

@@ -616,6 +616,8 @@
"body-file-collapse-1", "body-file-collapse-1",
"bouton", "bouton",
"breadcrumb", "breadcrumb",
"btnTOCShowLess",
"btnTOCShowMore",
"button", "button",
"button-group", "button-group",
"c4-diagram", "c4-diagram",
@@ -642,11 +644,11 @@
"docs", "docs",
"documentation", "documentation",
"dropdown-nav-0", "dropdown-nav-0",
"dropdown-panel-2a268a8b3931b61a7583f392002008fe", "dropdown-panel-084bf092239e5f25a71841b46134e2b5",
"dropdown-panel-5bf6f23e5fc93f9c342a4b0a1b32b838", "dropdown-panel-09e05d29554c47c7d092c3c332e8ab42",
"dropdown-panel-8cd9607610b5a8fff779d38787437e7e", "dropdown-panel-5acf6806020477b731604b7c3506126d",
"dropdown-panel-93636449c1ef8ec23d583052c9fe7a4b", "dropdown-panel-6bdf123559ba44e375634c7e5392b912",
"dropdown-panel-a97ffb4aaea3a2e4aa01b1ce556dd275", "dropdown-panel-d09398439fd994d4aafbc4a3a9c28bf2",
"elements-type", "elements-type",
"entity-relationship-diagram", "entity-relationship-diagram",
"example", "example",
@@ -664,11 +666,11 @@
"fab-medium", "fab-medium",
"fab-whatsapp", "fab-whatsapp",
"fab-x-twitter", "fab-x-twitter",
"faq-a69e21a1b0b61dac8b322b1d68137cc6", "faq-c3e9e2ab69a8c88825f39038d15bc04f",
"faq-a69e21a1b0b61dac8b322b1d68137cc6-heading-faq-a69e21a1b0b61dac8b322b1d68137cc6", "faq-c3e9e2ab69a8c88825f39038d15bc04f-heading-faq-c3e9e2ab69a8c88825f39038d15bc04f",
"faq-a69e21a1b0b61dac8b322b1d68137cc6-item-0", "faq-c3e9e2ab69a8c88825f39038d15bc04f-item-0",
"faq-a69e21a1b0b61dac8b322b1d68137cc6-item-1", "faq-c3e9e2ab69a8c88825f39038d15bc04f-item-1",
"faq-a69e21a1b0b61dac8b322b1d68137cc6-item-2", "faq-c3e9e2ab69a8c88825f39038d15bc04f-item-2",
"fas-1", "fas-1",
"fas-2", "fas-2",
"fas-3", "fas-3",
@@ -760,11 +762,11 @@
"nav-0-btn-1", "nav-0-btn-1",
"nav-0-btn-2", "nav-0-btn-2",
"nav-nav-0", "nav-nav-0",
"nav-panel-2a268a8b3931b61a7583f392002008fe", "nav-panel-084bf092239e5f25a71841b46134e2b5",
"nav-panel-5bf6f23e5fc93f9c342a4b0a1b32b838", "nav-panel-09e05d29554c47c7d092c3c332e8ab42",
"nav-panel-8cd9607610b5a8fff779d38787437e7e", "nav-panel-5acf6806020477b731604b7c3506126d",
"nav-panel-93636449c1ef8ec23d583052c9fe7a4b", "nav-panel-6bdf123559ba44e375634c7e5392b912",
"nav-panel-a97ffb4aaea3a2e4aa01b1ce556dd275", "nav-panel-d09398439fd994d4aafbc4a3a9c28bf2",
"navbar", "navbar",
"navbar-0-collapse", "navbar-0-collapse",
"navbar-mode", "navbar-mode",
@@ -773,36 +775,36 @@
"navigation", "navigation",
"notification", "notification",
"overview", "overview",
"panel-2a268a8b3931b61a7583f392002008fe-0", "panel-084bf092239e5f25a71841b46134e2b5-0",
"panel-2a268a8b3931b61a7583f392002008fe-1", "panel-084bf092239e5f25a71841b46134e2b5-1",
"panel-2a268a8b3931b61a7583f392002008fe-2", "panel-084bf092239e5f25a71841b46134e2b5-2",
"panel-2a268a8b3931b61a7583f392002008fe-btn-0", "panel-084bf092239e5f25a71841b46134e2b5-btn-0",
"panel-2a268a8b3931b61a7583f392002008fe-btn-1", "panel-084bf092239e5f25a71841b46134e2b5-btn-1",
"panel-2a268a8b3931b61a7583f392002008fe-btn-2", "panel-084bf092239e5f25a71841b46134e2b5-btn-2",
"panel-5bf6f23e5fc93f9c342a4b0a1b32b838-0", "panel-09e05d29554c47c7d092c3c332e8ab42-0",
"panel-5bf6f23e5fc93f9c342a4b0a1b32b838-1", "panel-09e05d29554c47c7d092c3c332e8ab42-1",
"panel-5bf6f23e5fc93f9c342a4b0a1b32b838-2", "panel-09e05d29554c47c7d092c3c332e8ab42-2",
"panel-5bf6f23e5fc93f9c342a4b0a1b32b838-btn-0", "panel-09e05d29554c47c7d092c3c332e8ab42-btn-0",
"panel-5bf6f23e5fc93f9c342a4b0a1b32b838-btn-1", "panel-09e05d29554c47c7d092c3c332e8ab42-btn-1",
"panel-5bf6f23e5fc93f9c342a4b0a1b32b838-btn-2", "panel-09e05d29554c47c7d092c3c332e8ab42-btn-2",
"panel-8cd9607610b5a8fff779d38787437e7e-0", "panel-5acf6806020477b731604b7c3506126d-0",
"panel-8cd9607610b5a8fff779d38787437e7e-1", "panel-5acf6806020477b731604b7c3506126d-1",
"panel-8cd9607610b5a8fff779d38787437e7e-2", "panel-5acf6806020477b731604b7c3506126d-2",
"panel-8cd9607610b5a8fff779d38787437e7e-btn-0", "panel-5acf6806020477b731604b7c3506126d-btn-0",
"panel-8cd9607610b5a8fff779d38787437e7e-btn-1", "panel-5acf6806020477b731604b7c3506126d-btn-1",
"panel-8cd9607610b5a8fff779d38787437e7e-btn-2", "panel-5acf6806020477b731604b7c3506126d-btn-2",
"panel-93636449c1ef8ec23d583052c9fe7a4b-0", "panel-6bdf123559ba44e375634c7e5392b912-0",
"panel-93636449c1ef8ec23d583052c9fe7a4b-1", "panel-6bdf123559ba44e375634c7e5392b912-1",
"panel-93636449c1ef8ec23d583052c9fe7a4b-2", "panel-6bdf123559ba44e375634c7e5392b912-2",
"panel-93636449c1ef8ec23d583052c9fe7a4b-btn-0", "panel-6bdf123559ba44e375634c7e5392b912-btn-0",
"panel-93636449c1ef8ec23d583052c9fe7a4b-btn-1", "panel-6bdf123559ba44e375634c7e5392b912-btn-1",
"panel-93636449c1ef8ec23d583052c9fe7a4b-btn-2", "panel-6bdf123559ba44e375634c7e5392b912-btn-2",
"panel-a97ffb4aaea3a2e4aa01b1ce556dd275-0", "panel-d09398439fd994d4aafbc4a3a9c28bf2-0",
"panel-a97ffb4aaea3a2e4aa01b1ce556dd275-1", "panel-d09398439fd994d4aafbc4a3a9c28bf2-1",
"panel-a97ffb4aaea3a2e4aa01b1ce556dd275-2", "panel-d09398439fd994d4aafbc4a3a9c28bf2-2",
"panel-a97ffb4aaea3a2e4aa01b1ce556dd275-btn-0", "panel-d09398439fd994d4aafbc4a3a9c28bf2-btn-0",
"panel-a97ffb4aaea3a2e4aa01b1ce556dd275-btn-1", "panel-d09398439fd994d4aafbc4a3a9c28bf2-btn-1",
"panel-a97ffb4aaea3a2e4aa01b1ce556dd275-btn-2", "panel-d09398439fd994d4aafbc4a3a9c28bf2-btn-2",
"persona", "persona",
"pie-chart", "pie-chart",
"pills", "pills",
@@ -839,6 +841,7 @@
"toast-example-2", "toast-example-2",
"toast-message-email-4", "toast-message-email-4",
"toc-collapse", "toc-collapse",
"toc-collapse-items",
"tooltip", "tooltip",
"types-de-cookies-que-nous-utilisons", "types-de-cookies-que-nous-utilisons",
"types-of-cookies-we-use", "types-of-cookies-we-use",

View File

@@ -101,6 +101,10 @@
translation: "See also" translation: "See also"
- id: sectionMenu - id: sectionMenu
translation: "Select a topic" translation: "Select a topic"
- id: tocShowMore
translation: "Show {{ . }} more"
- id: tocShowLess
translation: "Show less"
# Sidebar # Sidebar
- id: toggleSidebar - id: toggleSidebar

View File

@@ -99,6 +99,10 @@
translation: "Zie ook" translation: "Zie ook"
- id: sectionMenu - id: sectionMenu
translation: "Selecteer een onderwerp" translation: "Selecteer een onderwerp"
- id: tocShowMore
translation: "Toon {{ . }} meer"
- id: tocShowLess
translation: "Toon minder"
# Sidebar # Sidebar
- id: toggleSidebar - id: toggleSidebar

View File

@@ -1,107 +1,88 @@
{{- /* {{/*
Copyright 2023 Veriphor, LLC Copyright © 2025 The Hinode Team / Mark Dumay. All rights reserved.
Use of this source code is governed by The MIT License (MIT) that can be found in the LICENSE file.
Visit gethinode.com/license for more details.
*/}}
Licensed under the Apache License, Version 2.0 (the "License"); you may not {{ define "_partials/inline/toc-item.html" }}
use this file except in compliance with the License. You may obtain a copy of {{ $base := .base }}
the License at {{ $startLevel := .startLevel }}
{{ $endLevel := .endLevel }}
{{ $item := .item }}
{{ $maxNumHeadings := .maxNumHeadings }}
{{ $result := .result | default slice }}
https://www.apache.org/licenses/LICENSE-2.0 {{ if and (ge $item.Level $startLevel) (le $item.Level $endLevel) }}
{{- $attrs := dict "class" (printf "toc-item toc-level-%d" (add 1 (sub $item.Level $startLevel))) }}
{{- with $item.ID }}
{{- $attrs = merge $attrs (dict "href" (printf "%s#%s" $base .)) }}
{{- end }}
Unless required by applicable law or agreed to in writing, software {{ $htmlAttr := "" }}
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT {{ range $k, $v := $attrs }}{{ $htmlAttr = printf "%s %s=%q" $htmlAttr $k $v | safeHTMLAttr }}{{ end }}
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the {{ $rendered := printf "<a %s>%s</a>" $htmlAttr $item.Title }}
License for the specific language governing permissions and limitations under {{ $result = $result | append $rendered }}
the License. {{ end }}
*/}}
{{- /* {{ range $item.Headings }}
Renders a table of contents by parsing rendered content. {{ $result = $result | append (partial "inline/toc-item.html" (dict
"base" $base
"item" .
"startLevel" $startLevel
"endLevel" $endLevel
"maxNumHeadings" $maxNumHeadings
)) }}
{{ end }}
In site configuration, set the default start level, end level, and the minimum {{ return $result }}
number of headings required to show the table of contents: {{ end }}
[params.toc] {{- /* Get configuration. */}}
startLevel = 2 # default is 2 {{- $startLevel := or (.Site.Params.navigation.startLevel | int) 2 }}
endLevel = 3 # default is 3 {{- $endLevel := or (.Site.Params.navigation.endLevel | int) 3 }}
minNumHeadings = 2 # default is 2 {{- $minNumHeadings := or (.Site.Params.navigation.minNumHeadings | int) 2 }}
{{- $maxNumHeadings := or (.Site.Params.navigation.maxNumHeadings | int) 9 }}
To display the table of contents on a page: {{- /* Render */}}
{{- if and .Site.Params.navigation.toc (ge (len .Fragments.HeadingsMap) $minNumHeadings) }}
+++
title = 'Post 1'
toc = true
+++
To display the table of contents on a page, and override one or more of the
default settings:
+++
title = 'Post 1'
[toc]
startLevel = 2 # default is 2
endLevel = 3 # default is 3
minNumHeadings = 2 # default is 2
+++
Change or localize the title with a "toc_title" key in your i18n file(s).
Start with these basic CSS rules to style the table of contents:
a.toc-item {
display: block;
}
a.toc-level-1 {
margin-left: 0em;
}
a.toc-level-2 {
margin-left: 1em;
}
a.toc-level-3 {
margin-left: 2em;
}
a.toc-level-4 {
margin-left: 3em;
}
a.toc-level-5 {
margin-left: 4em;
}
a.toc-level-6 {
margin-left: 5em;
}
@context {page} .
@returns {template.HTML}
@example {{ partial "toc-parse-content.html" . }}
*/}}
{{- /* Get configuration. */}}
{{- $startLevel := or (.Site.Params.navigation.startLevel | int) 2 }}
{{- $endLevel := or (.Site.Params.navigation.endLevel | int) 3 }}
{{- $minNumHeadings := or (.Site.Params.navigation.minNumHeadings | int) 2 }}
{{- /* Initialize. */}}
{{ $headings := partial "assets/toc-headings.html" . }}
{{- /* Render */}}
{{- if .Site.Params.navigation.toc }}
{{- with $headings }}
{{- if ge (len .) $minNumHeadings }}
<strong class="d-block h6 my-2 pt-4">{{ T "toc" }}:</strong> <strong class="d-block h6 my-2 pt-4">{{ T "toc" }}:</strong>
<nav class="toc"> <nav class="toc">
{{- range . }} {{ $result := slice }}
{{- $attrs := dict "class" (printf "toc-item toc-level-%d" (add 1 (sub .level $startLevel))) }} {{ range .Fragments.Headings }}
{{- with .id }} {{ $result = $result | append (partial "inline/toc-item.html" (dict
{{- $attrs = merge $attrs (dict "href" (printf "%s#%s" $.RelPermalink .)) }} "base" $.RelPermalink
{{- end }} "item" .
<a "startLevel" $startLevel
{{- range $k, $v := $attrs }} "endLevel" $endLevel
{{- printf " %s=%q" $k $v | safeHTMLAttr }} "maxNumHeadings" $maxNumHeadings
{{- end -}} )) }}
>{{ .text }}</a> {{ end }}
{{- end }}
{{ range $i, $v := $result }}
{{ if eq $i $maxNumHeadings }}
{{ partial "assets/button.html" (dict
"id" "btnTOCShowMore"
"collapse-id" "toc-collapse-items"
"link-type" "link"
"class" "toc-item"
"title" (T "tocShowMore" (sub (len $result) $i))
"spacing" false
) }}
<div class="collapse" id="toc-collapse-items">
{{ end }}
{{ print $v | safeHTML }}
{{ end }}
{{ if gt (len $result) $maxNumHeadings }}
&nbsp;
{{ partial "assets/button.html" (dict
"id" "btnTOCShowLess"
"collapse-id" "toc-collapse-items"
"link-type" "link"
"class" "toc-item"
"title" (T "tocShowLess")
"spacing" false
) }}
</div>{{ end }}
</nav> </nav>
{{- end }} {{ end }}
{{- end }}
{{- end }}