arkadianriver

A Recursive Jekyll TOC

Using recursive include files in Jekyll for a simple TOC

04 Aug 2018

Note:

JULY 2019 UPDATE: Chris Oliver was able to contribute to the Jekyll documentation. Now the official tutorial doc has a recursive Jekyll ToC. Yay!"

None of the examples of site navigation in the Jekyll tutorials use recursion to go more than 3 levels deep. And I couldn’t find a method on the interwebs that was exactly what I wanted, although pretty close. Here, expanding on the method in Chris Oliver’s old 2011 post, this method passes the subtree as a parameter to the recursive call.

For example, let’s say you create a data file called contents.yml.

tree:
  - title: t1
    href: t1.html
  - title: t2
    href: t2.html
    tree:
      - title: t2A
        href: t2A.html
  - title: t3
    href: t3.html
    tree:
      - title: t3A
        href: t3A.html
        tree:
          - title: t3Ai
            href: t3Ai.html
            tree:
              - title: t3Aia
                href: t3Aia.html
                tree:
                  - title: t3Aaix
                    href: t3Aaix.html
      - title: t3B
        href: t3B.html
  - title: t4
    href: t4.html

And you create an include file named tree.html (accepting the passed tree param in include.tree on line 2 and recursion on line 4).

<ul>
{%- for item in include.tree -%}<li><a href="{{ item.href }}">{{ item.title }}</a>
{%-   if item.tree -%}
{%-     include tree.html tree=item.tree -%}</li>
{%-   else -%}</li>
{%-   endif -%}
{%- endfor -%}</ul>

You can then kick the whole thing off with a table of contents that includes the tree.html include file, passing site.data.contents.tree as its tree parameter.

{%- if site.data.contents.tree -%}
<div class="contents">
{%-   include tree.html tree=site.data.contents.tree -%}
</div>
{%- endif -%}