Add a text filter to generate the Table of Contents in the text

Created on 5 November 2025, 19 days ago

Problem/Motivation

toc_js currently exposes its TOC via a block. This works well for Layout Builder pages or theme-level placements (e.g., in a node Twig), but it does not give editors per-content, in-body control of where the TOC appears. They cannot place the TOC after an intro paragraph, between sections, etc.

This change adds a Text Filter that lets authors insert a simple token ([toc]) at the desired location in the body. The filter reuses the existing toc_js block (and its configuration/options) and renders that block output exactly where the token appears—delivering the same frontend behavior with much finer editorial control.

Steps to reproduce

  1. Enable toc_js and add its TOC via the provided block.
  2. Create a node with multiple headings (h2/h3).
  3. Attempt to place the TOC inside the body (e.g., after the first paragraph) without Layout Builder or theme overrides.
  4. Observe: it’s not possible—only block placement is available; token-based placement is missing.

Proposed resolution

Add a CKEditor 5-compatible Text Filter that:

  • Exposes the same configuration options as the existing toc_js block (heading levels/depth, label, container classes, etc.) on a per-Text-Format basis.
  • Programmatically renders the existing toc_js block at the token location, so output and behavior match the block 1:1.
  • Attaches the toc_js library exactly once; guards against duplicate attachments.
  • Ensures correct cacheability (contexts/tags/max-age) propagate from the block to the filter result.

User interface changes

  • New filter “Toc.js shortcode: [toc]” (provided by the toc_js_filter submodule) appears under Configuration → Content authoring → Text formats and editors.
  • Filter settings fieldset per Text Format mirrors the toc_js block options (heading levels, depth, label, classes, list type, numbering, anchor prefix, scope selector).
  • No new standalone admin pages.

API changes

  • None. Adds a new Text Filter in a submodule that reuses the existing toc_js block plugin; no public API changes in toc_js itself.

Data model changes

  • No new entities/tables.
  • New config schema for the filter’s per-Text-Format settings stored with Text Format config; keys mirror the block’s options.
Feature request
Status

Needs review

Version

3.3

Component

Code

Created by

🇧🇷Brazil gabriel.passarelli

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

No activities found.

Production build 0.71.5 2024