Hello everyone,
I’ve got some issues with the “Of anchors and ToCs, part 1” in CookBook. The first step works (Replace headlines with anchors) with the code :
<?php
Kirby::plugin('k-cookbook/toc', [
'hooks' => [
'kirbytext:after' => [
function($text) {
// get the headline levels to convert from a config option, we use h2 as the default
$headlines = option('k-cookbook.toc.headlines', 'h2|h3');
// create the regex pattern to be used as first argument in `preg_replace_callback()`
$headlinesPattern = is_array($headlines) ? implode('|', $headlines) : $headlines;
// use `preg_replace_callback()` to replace matches with anchors
$text = preg_replace_callback('!<(' . $headlinesPattern . ')>(.*?)</\\1>!s', function ($match) {
// create the id from the headline text
$id = Str::slug(Str::unhtml($match[2]));
// return the modified headline:
// $match[1] contains the match for the first subpattern, i.e. `h2`, `h3` etc.
// $match[2] contains the match for the second subpattern, i.e. the actual headline text
return '<' . $match[1] . ' id="' . $id . '"><a href="#' . $id . '">' . $match[2] . '</a></' . $match[1] . '>';
}, $text);
return $text;
},
]
]
]);
But then, I’m not sure how to add this first part to the second part for Generate the ToC
<?php
use Kirby\Toolkit\Collection;
use Kirby\Toolkit\Str;
use Kirby\Toolkit\Obj;
Kirby::plugin('k-cookbook/toc', [
'hooks' => [
'kirbytext:after' => [
// (…) add the callback function from above here (without the wrapper)
function($text) {
// the pattern allows passing an optional headline level `(toc: h3)`
$pattern = '!\(toc(?::\s?(h[1-6]))?\)!';
$text = preg_replace_callback($pattern, function($match) use($text) {
// get the headline level from the match
$headline = $match[1] ?? 'h2';
// find all headline matches
preg_match_all('!<' . $headline . '.*?>(.*?)</' . $headline . '>!s', $text, $matches);
// create a new collection for the headlines…
$headlines = new Collection();
// …and add all matches
foreach ($matches[1] as $text) {
$headline = new Obj([
'id' => $id = '#' . Str::slug(Str::unhtml($text)),
'url' => $id,
'text' => trim(strip_tags($text)),
]);
$headlines->append($headline->url(), $headline);
}
// return the html for the ToC
return snippet('toc', ['headlines' => $headlines], false);
}, $text);
return $text;
},
],
],
'snippets' => [
'toc' => __DIR__ . '/snippets/toc.php'
],
]);
I’m working on the starterkit on /content/notes
page, has anyone done this before ?
Thanks !