ToC for Bard & Markdown (Table of Contents) Icon

ToC for Bard & Markdown (Table of Contents)

2.2.0

August 9th, 2026

Housekeeping release. Nothing that ships changed: no file under src/, config/ or resources/ differs from 2.1.0, so an install of 2.2.0 behaves exactly like 2.1.0. Every tag parameter and template variable is unchanged.

Changed — the test suite runs on Statamic's own AddonTestCase

The 213-line hand-rolled tests/TestCase.php is gone. Fixtures moved into two traits, CreatesContent and RendersAntlers, and the suite now boots the way Statamic's own addon tests do. HarnessTest guards the harness itself, so a broken fixture fails loudly instead of silently skipping assertions.

Added — Marketplace listing artwork

art/ holds the product image (1280 × 800), cover and icon for the Marketplace listing.

Changed — art/ and screenshots/ are export-ignored

Listing artwork has no business in a consumer's vendor/ directory. The tarball is unchanged apart from this file.

2.1.0

August 5th, 2026

Housekeeping release. No template API changed; every tag parameter and template variable behaves exactly as in 2.0.0.

Fixed — Composer never autoloaded the test suite

All 13 classes under tests/Unit declared namespace Tests\Unit, while autoload-dev maps Goldnead\StatamicToc\Tests\. Composer therefore skipped every one of them when dumping the autoloader, and only PHPUnit's own file discovery still found the suite. Namespaces corrected.

Fixed — the parser facade documented a different class

src/Facades/ParserFacade.php carried a docblock advertising values(), strings() and numbers() and an @see Comparator — methods and a class belonging to something else entirely. The accessor was right; the IDE help was pointing at the wrong thing.

Fixed — four real static-analysis findings in Parser.php

The constructor returned $this, and three docblocks described types the code does not use. Fixed rather than written into a baseline. setContent(): object is deliberately left as is, so the v2 signature does not move.

Changed

  • require-dev is installable again. The orchestra/testbench range excluded what CI actually installed, and phpunit and php-cs-fixer were referenced by Composer scripts without being required. Formatting moves to Pint, which is required; composer lint has been broken since 1.9 and CI never noticed because it only ran composer test.
  • Larastan at level 5 with an empty baseline, and a CI leg for --prefer-lowest.
  • The published docs site no longer has <title>Document</title>.
  • .gitattributes keeps tests/, .github/ and docs/ out of the Composer tarball.
  • extra.statamic gains slug, url, developer and developer-url, so the addon card in the Control Panel links back to the developer instead of showing a blank.

The licence is unchanged and remains commercial: one production installation per licence, as LICENSE has always said. A note in the July 2026 studio baseline claiming it contradicted composer.json was a misreading and has been withdrawn.

2.0.0

August 5th, 2026

A rewrite of the internals behind an unchanged template API. Every tag parameter and every template variable from v1 still works and the output has the same shape; UPGRADE.md lists every behaviour that differs, and {{ toc:count }} is the one likely to need an edit.

  • Requires PHP 8.2 and Statamic 5 or 6. Statamic 3 and 4 stay on the v1 line. (Corrected 2026-07-31: that line is not maintained further. It ends at v1.10, which stays installable and receives no more fixes.)
  • league/commonmark is a declared dependency instead of something the addon hoped Statamic would bring along.
  • Heading extraction moved out of Parser into Extractors/{Bard,Html,Markdown} behind one interface, chosen by an explicit Detector. Content is no longer taken for markdown because it contains a #, and HTML without headings no longer falls through the markdown branch.
  • Extractors report every heading at every level plus any id already on it. Filtering by level moved to the caller, which is what lets the tag and the modifier eventually share one set of headings.
  • Dropped mb_convert_encoding(..., 'HTML-ENTITIES', ...), deprecated since PHP 8.2, and CommonMarkConverter::convertToHtml(), deprecated in league/commonmark 2.
  • The tag and the modifier now read their anchors from one shared registry instead of each running its own slug pass. Four defects go away with it: headings below the third level get ids; a from above a repeated heading no longer shifts the anchors under it; a hand-written id is used by the list instead of being slugged past; and two modifier calls on one page stop renumbering each other.
  • A heading that already carries an id keeps exactly that one. The old check missed an id in the last attribute position and appended a second, which is invalid HTML and left the anchor pointing nowhere.
  • Excluding a heading from the list no longer changes the anchors of the others.
  • New to parameter on the tag, an absolute level: {{ toc from="h2" to="h4" }}. depth keeps working and says the same thing relative to from; when both are given, to wins.
  • Breaking: {{ toc:count }} counts what the list shows. It used to force the depth to 6 and report a different number than the list right underneath it. Templates that relied on the old number to ask "are there any headings at all" want {{ toc:count depth="6" }}.
  • Options live in one immutable Options object instead of two mutable level fields recomputed from each other. Parser::flattenFrom(), an empty stub marked TODO since 2021, is gone.
  • An optional config file for the defaults, field, from, depth, to and flat. Publish it with --tag=statamic-toc-config. Without it the same defaults apply as before. Closes the oldest open issue, #6 from 2021.
  • Removed package.json. The addon has no JavaScript and no build step; the file declared an index.js that does not exist, stub scripts that exit with an error, and MIT, which contradicted the actual licence.
  • UPGRADE.md documents every behaviour change from v1.
  • CI runs PHP 8.2, 8.3 and 8.4 across Statamic 5 and 6.
  • Carries everything from v1.10, including the three anchor fixes and the guard against a malformed Bard node whose attrs arrive as an object. The v1.10 regression tests run unchanged against the rewrite, which is what says the two lines agree.

1.10

August 5th, 2026

Fixed — three ways an anchor pointed at nothing

All three end the same way for a reader: they click an entry in the table of contents and the page does not move. They had three separate causes, and tests/Unit/AnchorIntegrityTest.php pins each one.

Headings below h3 never got an id. Id injection ran over h1h3, because it reused the same maxLevel the list uses and that defaults to 3. A list configured deeper than three levels linked to h4s that carried no id at all. Injection now always spans h1h6, independently of the list: a heading outside the list is harmless with an id on it, while one inside it without an id is a dead link.

The tag's depth leaked into the modifier. The facade hands out one parser for the whole request and make() reset only the content and the slugs, so {{ toc depth="1" }} above an article silently removed the ids from every h2 and h3 in the article below it. The narrower the list, the more anchors broke — the exact opposite of what the parameter reads like it does. make() now resets depth, from, flatten and exclude to their defaults as well.

A heading that already had an id got a second one. The check for an existing id required a character after the closing quote, so an id written in the last attribute position — which is where people write it — was never seen:

#676E95;"><!-- in --> #89DDFF;"><h2#89DDFF;"> id#89DDFF;">=#89DDFF;">"mine#89DDFF;">"#89DDFF;">>Kept#89DDFF;"></h2#89DDFF;">>
#676E95;"><!-- out --> #89DDFF;"><h2#89DDFF;"> id#89DDFF;">=#89DDFF;">"mine#89DDFF;">"#89DDFF;"> id#89DDFF;">=#89DDFF;">"kept#89DDFF;">"#89DDFF;">>Kept#89DDFF;"></h2#89DDFF;">>

Two id attributes on one element is invalid HTML, a browser keeps the first, and the list linked to the second. The pattern no longer requires the trailing character, and ignores data-id and aria-id through a lookbehind rather than by accident. The list now also links to a hand-written id instead of slugging past it, so both halves name the same anchor.

Fixed — a malformed Bard node could fatal instead of being skipped

collectHeadingsRecursively() read $items['attrs']['level'], which throws Cannot use object of type stdClass as array when a node's attrs arrives as an object rather than an array. The null-coalesce does not protect against array access on an object. Both reads of attrs are guarded now (#39).

Added

  • New A Tailwind-styled starter-kit partial, {{ partial:statamic-toc::starter-kit }}. Publish it with php artisan vendor:publish --tag=statamic-toc-views to change the markup.
  • New The addon registers its view namespace explicitly, so partials resolve in package test suites too.

Notes

Still on PHP 7.4 and Statamic 3 through 6, unchanged. Nothing here alters the output for a document whose headings had no hand-written ids and whose list stayed at the default depth, which is the common case.

The mb_convert_encoding(..., 'HTML-ENTITIES', ...) deprecation notice on PHP 8.2 and up is not fixed here. Removing it means dropping PHP 7.4, so it waits for the v2 line.

1.9

July 30th, 2026

Führt die beiden offenen Bugfix-PRs #33 und #34 zusammen.

Behoben

  • Überschriften in verschachtelten Bard-Sets (Spalten, Grids, Replicator) werden jetzt gefunden. Vorher wurde nur die oberste Ebene gescannt.
  • Überschriften mit Inline-Formatierung behalten ihren vollen Text (#26). Vorher fiel eine Überschrift, die mit fett, kursiv oder Link beginnt, komplett aus der Liste, und eine mit Formatierung in der Mitte wurde abgeschnitten.
  • Keine Fatals mehr bei unsauberem Bard-Content: fehlende attrs, fehlender, leerer oder skalarer content und nicht-numerische Level werden übersprungen.
  • from() weitet die Level-Spanne nicht mehr auf, wenn es nach depth() oder zweimal aufgerufen wird.

Neu

  • exclude-Parameter am Tag: kommaseparierte Titel (Teilstring, case-insensitiv) oder ein Regex-Muster.

    {{ toc exclude#89DDFF;">=#89DDFF;">"Einleitung, Fußnoten#89DDFF;">" }}
    {{ toc exclude#89DDFF;">=#89DDFF;">"/^Anhang/i#89DDFF;">" }}

Intern

  • Die CI-Zeile für Statamic 5 lief nicht mehr: Composer installiert keine laravel/framework-Version unter 12 mehr, alle tragen ungepatchte Security-Advisories. Statamic 5 wird jetzt auf Laravel 12 getestet.
  • Drei Testklassen liefen unter PHPUnit 12 gar nicht, weil Doc-Comment-Annotationen dort nicht mehr gelesen werden. Die Suite geht von 20 auf 42 Tests.

Keine Breaking Changes. Alle Template-Variablen und Parameter bleiben unverändert.

1.8

April 8th, 2026

What's Changed

  • Allow installation on Statamic v6 by @j6s in https://github.com/goldnead/statamic-toc/pull/32

New Contributors

  • @j6s made their first contribution in https://github.com/goldnead/statamic-toc/pull/32

Full Changelog: https://github.com/goldnead/statamic-toc/compare/v1.7...v1.8

1.7

February 24th, 2025

Changes

Set default values for parent and has_children: Default values have been added in the Parser class to ensure parent is null and has_children is false, improving code robustness.

1.6

October 15th, 2024

  • remove Dependency of TidyPHP Extension
  • Improve handling of headings even when hierarchy structure isn't "correct". Avoids Error dumps.

Full Changelog: https://github.com/goldnead/statamic-toc/compare/v1.5...v1.6

1.5

July 9th, 2024

This release updates the dependencies and tests to ensure it runs properly on Statamic 5.

1.4

May 13th, 2023

Ensure through testing that Statamic 4 is still compatible.

1.3.1

October 29th, 2022

  • N/A Changelog not available.

1.3.0

October 29th, 2022

  • N/A Changelog not available.

1.2.0

June 7th, 2022

  • Thanks @jonassiewertsen for extending the testing matrix to statamic 3.3 and fixing some stuff in the readme.

What's Changed

  • Support Statamic 3.3 by @jonassiewertsen in https://github.com/goldnead/statamic-toc/pull/14
  • Fix typo in readme by @jonassiewertsen in https://github.com/goldnead/statamic-toc/pull/15
  • Fix readme examples by @jonassiewertsen in https://github.com/goldnead/statamic-toc/pull/16

New Contributors

  • @jonassiewertsen made their first contribution in https://github.com/goldnead/statamic-toc/pull/14

Full Changelog: https://github.com/goldnead/statamic-toc/compare/v1.1.0...v1.2.0

1.1.0

December 30th, 2021

What's Changed

  • Make Addon work with markdown content by @goldnead in https://github.com/goldnead/statamic-toc/pull/13

Full Changelog: https://github.com/goldnead/statamic-toc/compare/v1.0.10...v1.1.0

1.0.10

December 30th, 2021

What's Changed

  • Write Unit-tests by @goldnead in https://github.com/goldnead/statamic-toc/pull/12

Full Changelog: https://github.com/goldnead/statamic-toc/compare/v1.0.9...v1.0.10

1.0.9

November 9th, 2021

Fixes possible duplicate contents from being outputted when using multiple tags (including {{ toc:count }}).

Full Changelog: https://github.com/goldnead/statamic-toc/compare/v1.0.8...v1.0.9

1.0.8

November 8th, 2021

Fix wrong tree-output-bug introduced with last fix.

1.0.7

November 8th, 2021

Fix the counting result of total_results and the {{ toc:count }} tag.

1.0.6

November 8th, 2021

What's Changed

  • v1.0.6 by @goldnead in https://github.com/goldnead/statamic-toc/pull/11

Full Changelog: https://github.com/goldnead/statamic-toc/compare/v1.0.3...v1.0.6

1.0.5

July 8th, 2021

  • Fix somehow messed-up releases

1.0.4

July 8th, 2021

  • Add from support

1.0.3

July 8th, 2021

Fix Bug, where ToC-Tag did not output a list.

1.0.2

July 7th, 2021

Now, it's possible to also use the "HTML"-Mode in bard and still use this addon. Check the Readme for further details.

1.0.1

July 6th, 2021

First Patch!

1.0.0

July 6th, 2021

Initial Release