Skip to content
No description or website provided.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Kirby TOC - Table Of Contents

Version 0.1 MIT license Donate

Automatically generate a table of contents nested list of your content.

Installation instructions

By default the table of contents should now be visible at the top of all your pages.


The following options can be set in your /site/config/config.php file:

c::get('kirby.toc.class', 'toc');
c::set('kirby.toc.filters', ['headings', 'auto']);
c::set('', 'toc');
c::set('kirby.toc.replacement', '{{ toc }}');
c::set('kirby.toc.slug.method', function($heading) {
    return str::slug($heading);


By default the table of contents nested list will be wrapped by <div class="toc"></div>. You can't remove it, but you can set another class name if you want.

c::get('kirby.toc.class', 'table-of-contents');


By default two filters are used on the content to add the nested table of contents list.

c::set('kirby.toc.filters', ['headings', 'auto']);


This filter will add id attributes to all h1-h6 tags. The id is extracted from the heading text and converted to slugs with the str::slug() method by default.

## Hello h2


<h2 id="hello-h2">Hello h2</h2>

Be aware: If you already have an id on your heading tag, it will not be replaced with a new one.


This filter add the table of contents nested list at the top of the content.


This filter add the table of contents where you put a replacement tag. By default you can add {{ toc }} somewhere in your content and it will be replaced by the table of contents.

In case you don't want the table of contents of all your pages, you can use a field method instead of the filters.

Disable filters

You should not use both filters and a field method. Therefor you should disable the filters when using the field method.

c::set('kirby.toc.filters', []);

By default you can do something like this in your snippet/template:

echo $page->text()->kt()->toc()

Use another field method name

If you don't like the name of the field method you can change it like this:

c::set('', 'my_new_toc_name');


In case you use kirby.toc.filters with tag, you may want to change the tag name {{ toc }} to something else.

c::set('kirby.toc.replacement', '{{ my_toc_list }}');


By default, Kirby str::slug() method is used to convert headings into ids. It works well in english but for swedish words ä can be translated to ae which is not nice. In that case it should be a. Because of things like that you can replace the slug engine with your own.

c::set('kirby.toc.slug.method', function($heading) {
    return mySuperSlugMethod($heading);

Add the table of contents yourself

In case you need to add the table of contents nested list in your templates or snippets you can use the methods directly.

Something like below will present the nested table of contents list:

$TOC = new TOC();
echo $TOC->list($page->text()->kt());


To make the nested table of contents list look better you need to add some counters. Here is how to do that in CSS:

ol {
    counter-reset: section;
    list-style-type: none;

li::before {
    counter-increment: section;
    content: counters(section, ".") " ";



  • Initial release



This plugin is provided "as is" with no guarantee. Use it at your own risk and always test it yourself before using it in a production environment. If you find any issues, please create a new issue.



It is discouraged to use this plugin in any project that promotes racism, sexism, homophobia, animal abuse, violence or any other form of hate speech.


You can’t perform that action at this time.