Hey,
there is a template with text fields and layout fields.
I’m trying to integrate a table of content like in the cookbook (Anchors and ToCs | Kirby CMS)
When i include some h2 h3 in the text fields (not in Layout) the anchors are set to the headlines.
But no TOC appears!
plugins > toc > index.php
<?php
Kirby::plugin('lordcanis/toc', [
'hooks' => [
'kirbytext:after' => [
function($text) {
// get the headline levels to convert from a config option, we use h2 as the default
$headlines = option('lordcanis.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;
},
],
'fieldMethods' => [
'headlines' => function($field, $headline = 'h2') {
preg_match_all('!<' . $headline . '.*?>(.*?)</' . $headline . '>!s', $field->kt()->value(), $matches);
$headlines = new Collection();
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 $headlines;
}
],
'snippets' => [
'toc' => __DIR__ . '/snippets/toc.php'
],
]
]);
plugins > toc > snippets > toc.php
<?php if ($headlines->count() >= 3) : ?>
<nav class="toc">
<h2>Table of Contents</h2>
<ol>
<?php foreach($headlines as $headline): ?>
<li><a href="<?= $page->url() . '/#' . Str::slug($headline->text()) ?>"><?= $headline->text() ?></a></li>
<?php endforeach ?>
</ol>
</nav>
<?php endif ?>
config > config.php
...
'lordcanis.toc.headlines' => ['h2', 'h3'],
...
snippet in template
<?php snippet('toc', ['headlines' => $page->text()->headlines('h2|h3')]) ?>
snippets > blocks > heading.php
<?php /** @var \Kirby\Cms\Block $block */ ?>
<<?= $level = $block->level()->or('h2') ?> class="<?= $block->ausrichtung() ?>" id="<?= Str::slug($block->text()) ?>"><?= $block->text() ?></<?= $level ?>>
Why is there no toc?
How can i display the headline from the text fields and the layout field?
Thank you!