I wanted a plugin that transforms headings into headings with ids, similar to Github.
It turns this…
# Hello World
Some text
## Another heading
Another paragraph
…into this…
<h1 id="hello-world">Hello World</h1>
<p>Some text</p>
<h2 id="another-heading">Another heading</h2>
<p>Another paragraph</p>
Plugin code - Field method
The code below can be put into a plugin:
<?php
field::$methods['heading_ids'] = function($field) {
preg_match_all('|<h[^>]+>(.*)</h[^>]+>|iU', $field->value, $matches);
foreach($matches[1] as $item) {
$field->value = str_replace(
'>' . $item . '</h',
' id="' . str::slug($item) . '">' . $item . '</h',
$field->value
);
}
return $field;
};
Plugin code - Kirbytext post filter
If you prefer a kirbytext post filter, where there is no need to add a field method you can use the code below.
kirbytext::$post[] = function($kirbytext, $value) {
preg_match_all('|<h[^>]+>(.*)</h[^>]+>|iU', $value, $matches);
foreach($matches[1] as $item) {
$value = str_replace(
'>' . $item . '</h',
' id="' . str::slug($item) . '">' . $item . '</h',
$value
);
}
return $value;
};
Be aware that str::slug makes words like Bytesrätt into bytesraett. It turns ä into ae which is not nice for Swedish words. To fix it, you need to use something else like GitHub - cocur/slugify: Converts a string to a slug. Includes integrations for Symfony, Silex, Laravel, Zend Framework 2, Twig, Nette and Latte..
I noticed that @wottpal made a similar plugin that is much more advanced here: GitHub - wottpal/kirby-anchor-headings: A kirby field-method which enumerates heading-elements, generates IDs for anchor-links and inserts custom markup based on your options.

I’ve added it as well in my post. So if it’s going to be on all texts globally, use the kirbytext filter. If it should only be used on only some texts, a field method may be better.