Partial Hugo to generate a Table of Contents with `<details>` and `<summary>`

Hello everyone,

I wanted to share a partial I created to dynamically generate a Table of Contents (ToC) in Hugo, using the HTML <details> and <summary> tags for an expandable/collapsible effect.

The code first checks if the toc variable is enabled in the page’s frontmatter. Then, it detects the <h2> tags within the content. If only one <h2> tag is found, it switches to using <h3> tags instead. Links are automatically generated for each heading based on the IDs found in the HTML.

Here’s the code for the partial mytoc.html:

{{ if (eq $.Params.toc true)}}
<details class="notices tip">
  <summary class="label">Table of Contents</summary>
  <ul>
    {{ $headings := findRE "<h2.*?>(.|\n])+?</h2>" .Content }}
    {{ if (le (len $headings) 1) }}
      {{ $headings = findRE "<h3.*?>(.|\n])+?</h3>" .Content }}
    {{ end }}
    {{ range $headings }}
      {{ $id := findRE "id=\".*\"" . }}
      <li><a href="#{{ $id }}">{{ . | htmlUnescape | plainify }}</a></li>
    {{ end }}
  </ul>
</details>
{{ end }}

Capture d’écran 2024-10-15 122431

You can use .TableOfContents.

1 Like