caseyamcl/toc
caseyamcl/toc is a PHP library that generates a nested table of contents from HTML headings. It parses h1–h6 elements, adds anchor IDs, and outputs a customizable, hierarchical TOC list for documentation and long-form pages.
Architecture fit
<ul> TOC (and optionally heading anchors) out. It is a rendering concern, not a domain concern, so it belongs in the presentation layer (a Blade component, a view helper, or a small TocBuilder service), never in models or controllers directly.Integration feasibility
composer require caseyamcl/toc, wrap in a ~40-line adapter, expose as a Blade component. No DB, no queue, no external service, no credentials. An engineer can spike this against real content in under a day.ext-dom/libxml), which is present in essentially every standard Laravel runtime image; confirm it is enabled in our production and CI images rather than assuming.ext-dom only, the audit story is trivial.Technical risk
DOMDocument::loadHTML is HTML4-era and lossy: it can reorder/normalize markup on re-serialization, mishandle HTML5 elements (<section>, <figure>, custom elements), and mangle UTF-8 unless the document declares a charset or is pre-encoded. Since this library mutates headings and returns the document, the risk is not just a wrong TOC — it is silently corrupted article HTML.id attributes and deduplicated, otherwise deep links break or point at the wrong section.Key questions
DOMDocument, and/or a structured array of headings — and can we hand it a document we already parsed, to avoid parsing twice?id attributes on headings handled — preserved, overwritten, or deduplicated against generated ones?ext-dom only?Stack fit
TocService (or TocBuilder) in app/Support that takes a raw HTML string plus options (minLevel, maxLevel, anchorPrefix), returns a DTO { tocHtml, contentHtml }. A <x-toc> Blade component and a @toc directive sit on top. This keeps the third-party namespace out of views and gives us one seam to swap or fork later.sha1(contentHtml + options) in the response/view cache; article bodies are static per revision, so hit rates should be excellent.Migration path
Compatibility
ext-dom in prod/CI images, and interaction with our existing HTML sanitizer (mews/purifier or HTMLPurifier) and Markdown renderer (commonmark). Define a single canonical pipeline order and enforce it in one place.Sequencing
Maintenance
Dom\HTMLDocument support in PHP 8.4+) may make it redundant. Note it as a candidate for replacement in ~18–24 months.Support
Scaling
Failure modes
<ul>).Ramp-up
How can I help you explore Laravel packages today?