ToC with Blocks

Hi there,

I have a relatively simple question. I followed the example on how to create a table of contents from block headings in Extra: ToC from blocks field.

What is not so clear to me is how to call the snippet on my template.

I tried with something like this:

<?php snippet('toc', ['headlines' => $page->text()->toBlocks->filterBy('type', 'heading')->filterby('level', 'h2')]) ?>

But that doesn’t seem to be working despite that I followed other steps.

Would anyone be able to help?

How many h2 headlines are there in your blocks field? The toc snippet only shows the toc if there are at least 3

Thanks for replying! I have 3 headings. Before I didn’t have as many, and nothing happened. Right now, my previous code above is throwing the following error:

Undefined property: Kirby\Content\Field::$toBlocks

So I’m unsure how to combine the two examples on that page to make it work for me case (using blocks).

<?php snippet('toc', ['headlines' => $page->text()->headlines('h2')]) ?>

and

$headlines = $page->text()->toBlocks()->filterBy('type', 'heading')->filterby('level', 'h2');

I don’t know, I quickly tested it in a starterkit and it worked as intended. Make sure your field names are correct.

Thanks for checking. Could you please share with me how does it look that line on your template? — with Blocks?

My field name is the same than in the example.

I was missing () after Blocks, now it’s not giving any error but also not doing anything really.

toc.php snippet from recipe in /site/snippets

<?php if ($headlines->count() > 1) : ?>
	<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 ?>

In note.php template

<?php
$headlines = $page->text()->toBlocks()->filterBy('type', 'heading')->filterby('level', 'h2');

dump($headlines); // just to make sure I have headlines
snippet('toc', ['headlines' => $headlines]);

Thanks, I have it working now but it’s different from the recipe.

  • I don’t have / need a plugin like: /site/plugins/toc/snippets/toc.php ?
  • I had missed that the snippet goes directly in snippets/toc.php

The last thing that I’m trying to figure out is why the text inside the <a> is using <strong>Headline</strong — and so are the headings created with a prefix and suffix -strong?

Not for the blocks example, it’s optional, you can register snippets, templates, controllers etc. in a plugin or in the respective folders

Probably because you put it there, it’s not in the snippet, so must be in your content.

Indeed. I copied and pasted some sentence from other site, and as it pasted it with format I didn’t realise of that :person_facepalming: I guess it’s time to take a break if I didn’t pay attention to this. Thanks for your help.