Shortcodes within shortcodes not rendering

I’m using a shortcode to call a snippet of markdown text (300-odd lines).

As recommended by @jmooring in the post No TableOfContents when reusing content, the shortcode which calls the snippet is

{{ $src := "" }}
{{- if .IsNamedParams -}}
    {{- $src = .Get "src" -}}
{{- else -}}
    {{- $src = .Get 0 -}}
{{- end -}}
{{- with .Site.GetPage $src -}}
    {{- .RawContent -}}
{{- else -}}
    {{- errorf "Can't find snippet reference %q in topic %s." (.Get 0) .Position -}}
{{- end -}}

and I’m calling the shortcode with {{% snippet src="/snippets/mytopic/index.md" %}}

This renders my minitoc on the right - Hugo is parsing the headings in my snippet.

But none of the shortcodes inside the snippet are rendering. For example, I’ve got a simple shortcode which creates an aside for a block of text:

{{- $_hugo_config := `{ "version": 1 }` -}}
{{- $color := "secondary" -}}
    <div class="alert alert-{{ $color }}" role="alert">
    <h4 class="alert-heading">Note</h4>
    {{ .Inner | markdownify }}
    </div>

In the snippet, I call this with:

{{< note >}}
This is my note
{{< /note >}}

But in the rendered site, these shortcodes aren’t rendered.I’m guessing it’s because I’m using % % instead of < >

Am I stuck between rendered shortcodes and no minitoc or no shortcodes and a minitoc?

No.

The built-in table of contents (.TableOfContents) will not include headings from nested shortcodes, so we will build our own.

Take this for a spin.

The test page includes some content with headings, and calls the snippet shortcode. The snippet includes some content with headings, and calls the note shortcode.

git clone --single-branch -b hugo-forum-topic-42343 https://github.com/jmooring/hugo-testing hugo-forum-topic-42343
cd hugo-forum-topic-42343
hugo server

Files of interest:

  • layouts/_default/single.html
  • layouts/partials/toc.html (contains documentation in header)
  • assets/scss/_toc.scss

By generating the table of contents after Hugo renders the content, we can:

  • Have complete control over HTML structure and attributes (#8338)
  • Modify the heading id attribute in a heading render hook (#8383)
  • Control the start and end levels at the page level and/or site level (#9329)
  • Include raw HTML heading elements in our markdown
  • Generate HTML heading elements from shortcodes invoked with the {{< >}} notation
  • Detect heading elements without id attributes (warning)
  • Detect duplicate heading id attributes (error)
  • Avoid other known issues such as #4735, #6081, #7128, and #7158

Let me know if you run into any problems with the toc partial. I have tested it quite a bit, but I am sure there’s room for improvement.

On a large site, with TOCs on every page, this will have an impact on performance. I have no idea how much. I’ll run some tests in the next couple of days.

Finally, in your note shortcode, do not use a heading element for the title. The TOC will pick that up if your end level is low enough.

Hi @jmooring, thank you for helping.

I’m getting this when I serve your repo:

Error: add site dependencies: load resources: loading templates: "C:\temp\jmooring\hugo-forum-topic-42343\layouts\partials\toc.html:115:1": parse failed: template: partials/toc.html:115: function "continue" not defined

Is this a Hugo version problem maybe? I’m using 0.89.1 but am not wedded to it.

Yes, this is a version issue. The continue statement was added in the last 6 months or so.

1 Like

Your example works beautifully. I just need to implement it in my own repo now - much appreciated. I’ll come back and mark this as a solution when I’m done.

Thanks again!

1 Like

I made 1000 copies of the test file in the example repository above. I tested with the toc partial, and with the .TableOfContents method. Taking the average of 5 runs:

  • With the toc partial: 877 ms
  • With the .TableOfContents method[1]: 737 ms

The difference is 140 ms, about a 19% increase in build time.

But this is a simple site. It renders the markup and transpiles some Sass. If the site includes image processing, the build time will increase, but the difference between the two TOC methods will decrease as a percentage of total build time.

So for most sites I don’t think this is a significant performance hit.


  1. Result excludes many of the headings, which is expected. That’s why we took this approach. ↩︎

2 Likes

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