To follow along, install a Kirby Starterkit, create a /site/plugins/toc folder with an index.php inside and add some headlines in a textarea field, for example in one of the subpages of the /content/notes page.
Anchors in the text to which the ToC can link. While those could be added manually, it is much easier to auto-generate them from headlines. Anchors are useful even without a ToC, because you can link to these anchors from elsewhere.
A navigation list of links to these anchors usually at the top of the page or the sidebar, the actual ToC.
Consequently, we have to implement two steps:
Replace the headlines in the text with anchor headlines
Add the ToC where we want it to appear
Let's start with replacing the headlines in our text with anchors.
We can replace headlines automatically with a KirbyText hook or manually using a field method. The actual code to replace the headlines is the same, but we hook into different Kirby extensions.
Let's start with a kirbytext:after hook that converts all given headline levels into anchors whenever the kirbytext() method is called. We make the headline levels we want to convert configurable via a config option and use h2 and h3 headlines as defaults.
The important part here is the preg_replace_callback() function. It needs three parameters…
the search pattern ($headlinesPattern)
the callback function
the input ($text)
…and returns the modified string.
To include more headlines levels, you can set the k-cookbook.toc.headlines option in the config:
In this recipe we explored different ways to add anchor headlines and a ToC to pages.
You can also mix the hook that auto-generates anchor headlines with the headlines field method and the toc.php snippet to create the ToC in your templates rather than through a placeholder users add manually.
If you vote for generating the ToC via the field method in your templates, you can still give editor control whether to show a ToC on a page by page basis using a toggle or checkbox field in your blueprints, for example:
text: Show ToC
You could also only show the ToC if there is at least a given number of headlines by slightly modifying the toc.php snippet, for example, if there are at least 3 headlines: