Adding custom TOC in gohugotheme

Hi,

I am trying to add custom TOC which is right sidebar from the following article.

https://disaev.me/p/blog-engines-and-static-site-generators/#table-of-contents

I have added the following code in theme/gohugoioTheme/layouts/partials/toc.html

{{ $headers := findRE “<h[1-3].*?>(.|\n])+?</h[1-3]>” .Content }}

{{ $has_headers := ge (len $headers) 1 }}

{{ show_toc := (eq .Params.toc true) }}
{{ if and $has_headers $show_toc }}

Table of Contents

    {{ range $i, $header := $headers }} {{ $headerLevel := index (findRE "[1-3]" . 1) 0 }} {{ $headerLevel := len (seq $headerLevel) }}
  {{ $anchorID := ($header | plainify | htmlEscape | urlize) }}

  {{ if ne $i 0 }}
    {{ $prevHeaderLevel := index (findRE "[1-3]" (index $headers (sub $i 1)) 1) 0 }}
    {{ $prevHeaderLevel := len (seq $prevHeaderLevel) }}

      {{ if gt $headerLevel $prevHeaderLevel }}
        {{ range seq (sub $headerLevel $prevHeaderLevel) }}
          <ul class="nav">
        {{end}}
      {{end}}

      {{ if lt $headerLevel $prevHeaderLevel }}
        {{ range seq (sub $prevHeaderLevel $headerLevel) }}
          </li></ul></li>
        {{end}}
      {{end}}

      {{ if eq $headerLevel $prevHeaderLevel }}
        </li>
      {{end}}

      <li>
        <a href="#{{ $anchorID }}">{{ $header | plainify | htmlEscape }}</a>

      {{ if eq $i (sub (len $headers) 1) }}
        {{ range seq (sub $prevHeaderLevel $headerLevel) }}
          </li></ul></li>
        {{end}}
      {{end}}
  {{else}}
  <li>
    <a href="#{{ $anchorID }}">{{ $header | plainify | htmlEscape }}</a>
  {{end}}
{{end}}

{{ $firstHeaderLevel := len (seq (index (findRE "[1-3]" (index $headers 0) 1) 0)) }}
{{ $lastHeaderLevel := len (seq (index (findRE "[1-3]" (index $headers (sub (len $headers) 1)) 1) 0)) }}
{{ range seq (sub $lastHeaderLevel $firstHeaderLevel) }}
  </li></ul></li>
{{end}}
{{end}}

Added links, scripts and CSS in theme/gohugoioTheme/layouts/_default/baseof.html

Links:

link rel=“stylesheet” href=“https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css”>

Scripts:

script src=“https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js”>
!-- add after bootstrap.min.js -->
script src=“https://cdn.rawgit.com/afeld/bootstrap-toc/v1.0.1/dist/bootstrap-toc.min.js”>

CSS:
nav id=“toc” data-toggle=“toc”>
body data-spy=“scroll” data-target="#toc">

its not working as excepted.

Uploaded my code here

https://drive.google.com/open?id=1NymXF2QrsM0tBCEaQMGZKzdeTgTDb9qN

Please help me on this fix. @afeld

Is it rendering a table of contents at all, but just not as expected?

Yes its rendering but as not expected.

It looks like one of the scripts is requiring jquery. Try adding this to your baseof.html:

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>

(From getbootstrap.com)

Thanks @marcia. Appreciate your help!!

I have added jquery-3.3.1.slim.min.js but still i am not getting the UI.

I have added Unminified versions of .css, .js and jquery-3.3.1.slim.min.js files and i am getting little better UI look but still not able to render perfectly.

I have uploaded my latest version of source code at https://drive.google.com/drive/folders/1DH7iibsbxtbEy8Hzgwrfak0IPFSoZn4z?usp=sharing

please take a look and give me some inputs.

In the following article https://disaev.me/p/blog-engines-and-static-site-generators/#table-of-contents

all the TOC heading css is in <h2> and <h3> or <h4> tags

but when i compile or run my TOC headings are in <ul> and <li> tags

i am thinking this is causing issues. Please take a look at my source and help.

@afeld Please take a look.

@RickCogley @zwbetz Please take a look if you have any idea on this.

If the scripts you need are not loading, then stuff that depends on them won’t work. Use your browser’s dev console to figure out if things are being loaded correctly.

All the .css and .js scripts are loading exactly.

The problem i have is in the body section the headings has <h1> or <h2> or <h3> css tags but in my TOC section headings as <ul> and <li> css tags. I would like to change the TOC headings tags to <h1> or <h2> or <h3> CSS tags. Let me know how can i do this change.

The rendered TOC section will be ul and li’s. Each will be a link with an id. The id ties it to the header tag so you can jump to a particular header on the page and also have the toc update based on the scroll position in the page.

I am testing the plugin in an html file, completely outside of Hugo. It just displays some links in the toc but doesn’t expand to subheadings or display the position based on scrolling. No errors are shown. I feel like I’m missing a component somewhere.

Thanks Again. @marcia

Can you refer me some TOC which works similarly so that i can plugin to my application.

Okay I got it working in an html file. Haven’t tried it in Hugo, but hope this helps. The scripts need to be in a particular order and need to be after the content before the ending body tag. So based on the plugin requirements you will need:

Between the head tags you need:

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

and

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!-- add after bootstrap.min.css -->
<link
rel="stylesheet"
href="https://cdn.rawgit.com/afeld/bootstrap-toc/v1.0.1/dist/bootstrap-toc.min.css"
/>

The body tag has to have:

<body data-spy="scroll" data-target="#toc">

The placeholder for the table of contents will look like this:

<nav id="toc" data-toggle="toc" class="sticky-top"></nav>

Scripts go at the bottom right before the end body tag.

<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<!-- add after bootstrap.min.js -->
<script src="https://cdn.rawgit.com/afeld/bootstrap-toc/v1.0.1/dist/bootstrap-toc.min.js"></script>
1 Like

I have added all the changes but its not rendering.

When i add bootstrap.min.css script file my UI is completely messed up

Before adding bootstrap.min.css :

After Adding bootstrap.min.css :

Please take a look at my hugo source code at
https://drive.google.com/open?id=1DH7iibsbxtbEy8Hzgwrfak0IPFSoZn4z