HUGO

Check for empty .TableOfContents

Hello everyone,

is this the proper way to check if the .TableOfContents is empty?

{{ if (and (ne .TableOfContents "<nav id=\"TableOfContents\"></nav>") (ne .TableOfContents "")) }}

I had tried just the empty string, but on some pages it seems to create the <nav> tags even though there is no headers to parse.

I don’t use table of contents and can’t test that snippet, but it looks wrong to me. you are basically telling the script:

IF
the .tableOfContents DOES NOT contain an empty nav element
OR
the .tableOfContents IS NOT empty

so it’s the proper way to know it’s NOT empty… Or I am confused.

I would exchange the and with an or.

Or:

{{ with .TableOfContents }}
  <!-- the variable is set -->
  {{ if ne .TableOfContents "<nav id=\"TableOfContents\"></nav>" }}
    <!-- the variable is not an empty navigation -->
    {{ . }}
    <!-- it's a dot because we are inside of a `with` -->
  {{ end }}
{{ end }}

PS: there is also a frontmatter variable that disables the TOC per post:

toc: false

So if you KNOW that it will be empty you could disable it and the parser would probably already skip at the with part of my code sample.

If I do an “OR”, it will always be true at least with the not equals.

  • Because if .TableOfContents is “”, it is not equal to the empty <nav>.
  • and if it is the empty <nav> it is not equal to “”.
  • if it has content, it is neither.

My version checks if it is not equal to the empty <nav> AND not equal to “”. In that case it contains some navigational elements.

The toc: false does only work if you use a conditional in your template. And since I have to use an if clause anyway, I thought I could just check for the empty .TableOfContents and not force my users (me) to remember setting the front matter parameter.

What confused me was that on some pages it contained an empty <nav> instead of being completely empty.

I do like your with version, but since I am new to Hugo, I wasn’t sure how to use that yet. But after reading about it, I think the if clause just needs to have the dot too, not `.TableOfContents, right?

right. the . inside of a {{ with $something }} is identical to $something. So if you “with” a .Page you can (not can, have to) write .Title inside instead of .Page.Title. It’s called “context” and you will find lot’s of solutions in this forum that just say something about “the context” and don’t go deeper but everyone “understands” :slight_smile: . I think you will understand EVERYTHING when reading the following link (and take your time and read all the other posts in that site too, it’s all very good and understandably written, @regis is an explainer-god):

1 Like