A Recursive Jekyll TOC

Using recursive include files in Jekyll for a simple TOC

4 August 2018
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 -%}

by:
Gary Faircloth

http://arkadianriver.com
Opinions expressed are his own and don't necessarily reflect the views of the company he works for or its members. Interests: tech, science, history, PC Gam...SQUIRREL!