PHPackages                             ideea/toc - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. ideea/toc

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

ideea/toc
=========

Simple Table-of-Contents Generator for PHP. Generates TOCs based off H1...H6 tags

v2.0(7y ago)023.2k↓39.1%MITPHPPHP &gt;=5.4

Since Feb 2Pushed 7y ago1 watchersCompare

[ Source](https://github.com/ideea/toc)[ Packagist](https://packagist.org/packages/ideea/toc)[ Docs](http://github.com/caseyamcl/toc)[ RSS](/packages/ideea-toc/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (5)Versions (5)Used By (0)

PHP TOC Generator
=================

[](#php-toc-generator)

Generates a Table of Contents from *H1...H6* Tags in HTML Content

[![Build Status](https://camo.githubusercontent.com/c1c462b6ac6e6d7b5c7afebb4e2424e92972661c4f1e1b753c80d19046266780/68747470733a2f2f7472617669732d63692e6f72672f6361736579616d636c2f746f632e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/caseyamcl/toc)

This package provides a simple, framework-agnostic library to build a Table-of-Contents from HTML markup. It does so by evalutating your *H1...H6* tags. It can also automatically add appropriate *id* anchor attributes to header tags so that in-page links work.

Features:

- Generates HTML menus and [KnpMenu Item](https://github.com/KnpLabs/KnpMenu) Menus
- Adds anchor ID attributes to *H1*...*H6* tags in your content where they do not already exist
- You can specify which *H1*...*H6* heading tag levels to include in the TOC
- Includes a Twig Extension for generating TOCs and compatible markup directly from templates
- Uses the flexible [KnpMenu Library](https://github.com/KnpLabs/KnpMenu) to generate menus
- PSR-0 thru PSR-2 Compliant
- Composer-compatible
- Unit-tested

In the spirit of [KISS philosophy](http://en.wikipedia.org/wiki/KISS_principle), this library makes a few assumptions:

1. The hierarchy of your content is defined solely by the header (*H1*...*H6*) tags. All other tags are ignored when generating the TOC.
2. The link titles in the Table of Contents match either the `title` attribute of the header tag, or if there is no `title`, the plaintext body of the header tag.

Installation Options
--------------------

[](#installation-options)

Install via [Composer](http://getcomposer.org/) by including the following in your `composer.json` file:

```
{
    "require": {
        "caseyamcl/toc": "~1.0",
    }
}

```

Or, drop the `src` folder into your application and use a [PSR-4 autoloader](http://www.php-fig.org/psr/psr-4/) to include the files.

Usage
-----

[](#usage)

This package contains two basic classes:

1. `TOC\MarkupFixer`: Adds `id` anchor attributes to any *H1*...*H6* tags that do not already have any (you can specify which header tag levels to use at runtime)
2. `TOC\TocGenerator`: Generates a Table of Contents from HTML markup

Basic Example:

```
$myHtmlContent = fix($myHtmlContent) . "";

// This generates the Table of Contents in HTML
$htmlOut .= "" . $tocGenerator->getHtmlMenu($myHtmlContent) . "";

echo $htmlOut;
```

Twig Integration
----------------

[](#twig-integration)

This library includes a [Twig](http://twig.sensiolabs.org) extension that enables you to load TOC lists and add anchors to markup from your Twig templates.

In order to enable Twig integration, you must register the `TocTwigExtension` with your Twig environment:

```
$myTwig = new \Twig_Environment();
$myTwig->addExtension(new TOC\TocTwigExtension());
```

Specifically, the extension adds a Twig function for generating Table of Contents HTML:

```
{# Generates HTML markup for given htmlContent #}
{{ toc(htmlContent) }}
```

It also provides a function and a filter for ensuring that your content includes anchors for all HTML header tags. They both do the same thing, so choose which one suits your needs best:

```
{# Adds anchor links (id tags) for given htmlContent #}
{{ add_anchors(htmlContent) }}

{# You can also use it as a filter #}

    {{ htmlContent | add_anchors }}

```

Your HTML content may be hard-coded in your Twig Template. An easy way to accomodate this is to make sure the content is surrounded by `{% block %}...{% endblock %}` tags, and then just pass in that block to the *toc* function.

For example:

```
{% extends 'base.html.twig' %}
{% block page_content %}

   {{ toc(add_anchors(block('my_writeup'))) }}

   {{ add_anchors(block('my_writeup')) }}

{% endblock %}

{% block my_writeup %}
Hi There
Lorum ipsum baz biz etecetra
This is some content
More content here.  Blah blah
{% endblock %}
```

Specifying Heading Levels to Include
------------------------------------

[](#specifying-heading-levels-to-include)

You can choose to include only specific *h1...h6* heading levels in your TOC. To do this, pass two additional arguments to the `TocGenerator::getHtmlMenu()` method: `$topLevel` and `$depth`. For example:

```
$tocGenerator = new TOC\TocGenerator();

// Get TOC using h2, h3, h4
$toc->getHtmlMenu($someHtmlContent, 2, 3);

// Get TOC using h1, h2
$toc->getHtmlMenu($someHtmlContent, 1, 2);

// Get TOC using h4, h5, h6
$toc->getHtmlMenu($someHtmlContent, 4, 3);
```

Most other methods in the package handle these arguments as well:

```
$tocGenerator = new TOC\TocGenerator();
$markupFixer = new TOC\MarkupFixer();

// Get KnpMenu using h1, h2, h3
$tocGenerator->getMenu($someHtmlContent, 1, 3);

// Fix markup for h3, h4 tags only
$markupFixer->fix($someHtmlContent, 3, 2);
```

Twig functions and filters accept these arguments as well:

```
{# Generate TOC using h2, h3 tags #}
{{ toc(my_content, 2, 3) }}

{# Add anchors to h4, h5, h6 tags #}
{{ my_content | add_anchors(4, 3) }}
```

Customizing Menu Output
-----------------------

[](#customizing-menu-output)

You can customize the rendering of lists that the `TocGenerator` class outputs. By default, `TocGenerator` uses the [KnpMenu ListRenderer](https://github.com/KnpLabs/KnpMenu/blob/master/src/Knp/Menu/Renderer/ListRenderer.php) class to output the HTML.

You can pass your own instance of the `ListRenderer` class to `TocGenerator::getHtmlMenu()`. Or, you can pass in your own renderer (implements [`Knp\Menu\Renderer\RendererInterface`](https://github.com/KnpLabs/KnpMenu/blob/master/src/Knp/Menu/Renderer/RendererInterface.php)).

For example, you may wish to use different CSS classes for your list items:

```
$options = [
    'currentAsLink' => false,
    'currentClass'  => 'curr_page',
    'ancestorClass' => 'curr_ancestor',
    'branch_class'  => 'branch
];

$renderer = new Knp\Menu\Renderer\ListRenderer(new Knp\Menu\Matcher\Matcher(), $options);

// Render the list
$tocGenerator = new TOC\TocGenerator();
$listHtml = $tocGenerator->getHtmlMenu($someHtmlContent, 1, 6, $renderer);
```

#### Customizing with Twig

[](#customizing-with-twig)

The KnpMenu library offers more robust integration with the [Twig Templating System](http://twig.sensiolabs.org/)than is offered by default with this library. You can take advantage of it by using the [TwigRenderer](https://github.com/KnpLabs/KnpMenu/blob/master/doc/02-Twig-Integration.markdown#using-the-twigrenderer)that is bundled with KnpMenu:

```
$twigLoader = new \Twig_Loader_Filesystem(array(
    __DIR__.'/vendor/KnpMenu/src/Knp/Menu/Resources/views',
    // ...paths to your own Twig templates that render KnpMenus...
));

$twig = new \Twig_Environment($twigLoader);
$itemMatcher = \Knp\Menu\Matcher\Matcher();
$menuRenderer = new \Knp\Menu\Renderer\TwigRenderer($twig, 'knp_menu.html.twig', $itemMatcher);

$tocGenerator = new TOC\TocGenerator();

// Output the Menu using the template
echo $menuRenderer->render($tocGenerator->getMenu($someHtmlContent));
```

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity26

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 84.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~458 days

Total

4

Last Release

2747d ago

Major Versions

v1.2 → v2.02018-11-09

### Community

Maintainers

![](https://www.gravatar.com/avatar/b73421848a02d75b947de5b431006ec12b3a3c4d246c699b5182aff78cb6c339?d=identicon)[ideea](/maintainers/ideea)

---

Top Contributors

[![caseyamcl](https://avatars.githubusercontent.com/u/53035?v=4)](https://github.com/caseyamcl "caseyamcl (45 commits)")[![ideea](https://avatars.githubusercontent.com/u/318955?v=4)](https://github.com/ideea "ideea (6 commits)")[![Schlaefer](https://avatars.githubusercontent.com/u/143224?v=4)](https://github.com/Schlaefer "Schlaefer (2 commits)")

---

Tags

TOCtable-of-contents

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/ideea-toc/health.svg)

```
[![Health](https://phpackages.com/badges/ideea-toc/health.svg)](https://phpackages.com/packages/ideea-toc)
```

###  Alternatives

[caseyamcl/toc

Simple Table-of-Contents Generator for PHP. Generates TOCs based off H1...H6 tags

92344.9k5](/packages/caseyamcl-toc)[j0k3r/php-readability

Automatic article extraction from HTML

186808.8k6](/packages/j0k3r-php-readability)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
