Extend .TableOfContents from within shortcode

Hi,
As I see toc is generated only from markdown files.
But is there an option to add some items to toc for example from shortcode or template?

For example:
content/index.md using <example> shortcode
shortcodes/example.html <h2>Example</h2>

I would expect to see Example on toc on generated page.

You will have to use a custom partial like this: {{- $headers := findRE "<h[2-4].*>(.|\n])+</h[2-4]>" .Content -}}. This will find all h2 to h4 from the .Content which also includes Shortcodes.

Here’s my entire TOC if it helps:

<div>
  {{- $headers := findRE "<h[2-4].*>(.|\n])+</h[2-4]>" .Content -}}
  {{- .Scratch.Set "lastLevel" 1 -}}
  {{- $hasHeaders := ge (len $headers) 1 -}}
  {{- if $hasHeaders -}}
    <ul class = "uk-nav"  uk-scrollspy-nav = "cls: uk-active; closest: li; scroll: true">
      {{- range $headers -}}
        {{- $lastLevel := $.Scratch.Get "lastLevel" -}}
        {{- $header := . -}}
        {{- $base := $.Path -}}
        {{- $anchorId := ($header | plainify | htmlUnescape | anchorize) -}}
        {{- $href := delimit (slice $base $anchorId) "#" | string -}}
        {{- range findRE "[2-4]" . 1 -}}
          {{- $nextLevel := (int .) -}}
          {{- if gt $nextLevel $lastLevel -}}
            {{- range seq (add $lastLevel 1) $nextLevel -}}
              <li>
                <ul class = "toc-h{{- . -}}">
            {{- end -}}
          {{- else if lt $nextLevel $lastLevel -}}
            {{- range seq (add $nextLevel 1) $lastLevel -}}
                </ul>
              </li>
            {{- end -}}
          {{- end -}}
          <li>
            <a href = "{{- replace (relref $.Page $href) ($.RelPermalink) `` -}}" class = "uk-text-truncate" uk-scroll data-turbo = "false">
              {{- $header | plainify | htmlUnescape -}}
            </a>
          </li>
          {{- $.Scratch.Set "lastLevel" $nextLevel -}}
        {{- end -}}
      {{- end -}}
      </ul>
    </ul>
  {{- end -}}
</div>
1 Like

See https://gohugo.io/content-management/shortcodes/#shortcodes-with-markdown.

Shortcodes using the % as the outer-most delimiter will now be fully rendered when sent to the content renderer. They can be part of the generated table of contents, footnotes, etc.

content/post/test.md

+++
title = "Test"
date = 2021-03-27T04:48:08-07:00
draft = false
introduction = "This is the introduction."
conclusion = "This is the conclusion."
+++

{{% my-shortcode introduction %}}

{{% my-shortcode conclusion %}}

layouts/shortcodes/my-shortcode.html

{{ with $topic := .Get 0 }}
  ## {{ $topic | title }}
  {{ index $.Page.Params $topic }}
{{ else }}
  {{ errorf "The %s shortcode requires a single positional parameter. See %s" .Name .Position }}
{{ end }}

Produces this HTML.

<nav id="TableOfContents">
  <ul>
    <li><a href="#introduction">Introduction</a></li>
    <li><a href="#conclusion">Conclusion</a></li>
  </ul>
</nav>
<h1>Test</h1>
<h2 id="introduction">Introduction</h2>
<p>This is the introduction.</p>
<h2 id="conclusion">Conclusion</h2>
<p>This is the conclusion.</p>
2 Likes

Thanks guys.
That was very helpfull.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.