Nifty Code #3: Document Outline

Read more nifty code write-ups.

When I started the recipe block, I knew that I wanted to allow control over the section heading levels. I felt it wouldn’t be possible to assume fixed heading levels – should the Recipe Title be an h2, and the “ingredients” heading be h3? What if the post title is the recipe title, and the Recipe Title block is deleted?

First, I solved this by copying down the HeadingToolbar component. This let me use the same heading options that the heading block uses. Unfortunately, these would always show in the block’s toolbar, regardless of whether you’re editing the title or the list content.

Editing the ingredients section. My cursor is in the list, but it still looks like I can change the heading level of this text.
The Editor top bar with Content Structure highlighted.

These headings were also missing from the Document Outline — a helpful section for organizing your heading levels, under the Content Structure icon in the top toolbar.

After looking at the code for the Document Outline, I discovered it only includes content from the core/heading block. Well, that’s OK – I can use the same InnerBlocks approach as in the parent block.

Instead of setting up a template for editing, I only want one block in this instance of InnerBlocks. This time, I’ll set templateLock="all" to lock it down to only the blocks I provide in template. The template prop also lets me set a default value, so I can add the editable default title “Ingredients”, and set it to an initial level of h3.

And with that, we now have all the headings in our Document Outline, and the bonus: the heading style toolbar only appears when you’re editing the heading, and we can remove our custom implementation 🙂

The Document Outline section, with headings pulled from the Recipe content, indicated with Block name breadcrumbs next to each heading (ex: Recipe H2 Oven Roasted Squash, Recipe Ingredients H3 Ingredients, etc)

You can check out the relevant code on github (link to the specific section). I also had to add a deprecation migration to the block. I’m already using the block on my personal recipe site, and the new method was a breaking change. I’ll do a future post on that soon 👍🏻

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: