PHP 简单的目录生成器。根据 H1...H6 标签生成目录

v3.0.3 2021-12-07 05:15 UTC

This package is auto-updated.

Last update: 2024-09-07 11:25:12 UTC


README

从 HTML 内容中的 H1...H6 标签生成目录

Latest Version on Packagist Software License Github Build Code coverage PHPStan Level 8 Total Downloads

注意:此库现在需要 PHP 7.2 或更高版本;为了保留 PHP5-7.1 支持,请使用以下 composer 指令: composer require boomdevs/toc ~2.0.0

此软件包提供了一个简单、框架无关的库,用于从 HTML 标记构建目录。它是通过评估您的 H1...H6 标签来完成的。它还可以自动添加适当的 id 锚点属性到标题标签,以便页面内的链接可以正常工作。

功能

  • 生成 HTML 菜单和 KnpMenu Item 菜单
  • 在内容中添加锚点 ID 属性到不存在的 H1...H6 标签
  • 您可以选择要包含在目录中的 H1...H6 标题标签级别
  • 包括用于在模板中直接生成目录和兼容标记的 Twig 扩展
  • 使用灵活的 KnpMenu 库 生成菜单
  • 符合 PSR-12 规范
  • 兼容 Composer
  • 单元测试(95%覆盖率)

在 KISS(保持简单,做好)原则的精神下,此库做了一些假设

  1. 您的内容层次结构仅由标题(H1...H6)标签定义。生成目录时,会忽略所有其他标签。
  2. 目录中的链接标题与标题标签的 title 属性匹配,或者如果没有 title,则与标题标签的(缩写)纯文本主体匹配。

安装选项

通过将以下内容添加到您的 composer.json 文件中,使用 Composer 进行安装

{
    "require": {
        "boomdevs/toc": "^3.0",
    }
}

或者,将 src 文件夹放入您的应用程序中,并使用 PSR-4 自动加载器 包含文件。

用法

此软件包包含两个主要类

  1. TOC\MarkupFixer:为任何尚未具有任何 id 锚点属性的 H1...H6 标签添加 id 锚点属性(您可以在运行时指定要使用的标题标签级别)
  2. TOC\TocGenerator:从 HTML 标记生成目录

基本示例

$myHtmlContent = <<<END
    <h1>This is a header tag with no anchor id</h1>
    <p>Lorum ipsum doler sit amet</p>
    <h2 id='foo'>This is a header tag with an anchor id</h2>
    <p>Stuff here</p>
    <h3 id='bar'>This is a header tag with an anchor id</h3>
END;

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

// This ensures that all header tags have `id` attributes so they can be used as anchor links
$htmlOut  = "<div class='content'>" . $markupFixer->fix($myHtmlContent) . "</div>";

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

echo $htmlOut;

这将生成以下输出

<div class='content'>
    <h1 id="this-is-a-header-tag-with-no-anchor-id">This is a header tag with no anchor id</h1>
    <p>Lorum ipsum doler sit amet</p>
    <h2 id="foo">This is a header tag with an anchor id</h2>
    <p>Stuff here</p>
    <h3 id="bar">This is a header tag with an anchor id</h3>
</div>
<div class='toc'>
    <ul>
        <li class="first last">
        <span></span>
            <ul class="menu_level_1">
                <li class="first last">
                    <a href="#foo">This is a header tag with an anchor id</a>
                    <ul class="menu_level_2">
                        <li class="first last">
                            <a href="#bar">This is a header tag with an anchor id</a>
                        </li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</div>

Twig 集成

此库包含一个 Twig 扩展,允许您从 Twig 模板中加载 TOC 列表并添加锚点到标记。

为了启用 Twig 集成,您必须将 TocTwigExtension 注册到您的 Twig 环境中

use Twig\Environment;
use Twig\Loader\FilesystemLoader;

$myTwig = new Environment(new FilesystemLoader());
$myTwig->addExtension(new TOC\TocTwigExtension());

具体来说,此扩展添加了一个用于生成目录 HTML 的 Twig 函数

{# Generates HTML markup for given htmlContent #}
<ul>{{ toc(htmlContent) }}</ul>

它还提供了一个函数和一个过滤器,以确保您的所有内容都包含所有 HTML 标题标签的锚点。它们都做同样的事情,所以选择最适合您需求的一个

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

{# You can also use it as a filter #}
<div class='my_content'>
    {{ htmlContent | add_anchors }}
</div>

您的 HTML 内容可能硬编码在您的 Twig 模板中。一种简单的方法是确保内容被 {% block %}...{% endblock %} 标签包围,然后将该块传递给 toc 函数。

例如

{% extends 'base.html.twig' %}
{% block page_content %}
<div class='page_sidebar'>
   {{ toc(add_anchors(block('my_writeup'))) }}
</div>

<div class='page_content'>
   {{ add_anchors(block('my_writeup')) }}
</div>
{% endblock %}

{% block my_writeup %}
<h1>Hi There</h1>
<p>Lorum ipsum baz biz etecetra</p>
<h2>This is some content</h2>
<p>More content here.  Blah blah</p>
{% endblock %}

指定要包含的标题级别

您可以选择只包含特定 h1...h6 标题级别在您的目录中。为此,将两个额外的参数传递给 TocGenerator::getHtmlMenu() 方法:$topLevel$depth。例如

$tocGenerator = new TOC\TocGenerator();
$someHtmlContent = '<div><h1>Test</h1><p>Lorum ipsum</p><h2>Test2</h2><p>Lorum ipsum</p></div>';

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

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

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

软件包中的大多数其他方法都处理这些参数

$tocGenerator = new TOC\TocGenerator();
$markupFixer = new TOC\MarkupFixer();
$someHtmlContent = '<div><h1>Test</h1><p>Lorum ipsum</p><h2>Test2</h2><p>Lorum ipsum</p></div>';


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

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

Twig函数和过滤器也接受这些参数

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

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

自定义菜单输出

您可以为TocGenerator类输出的列表进行自定义渲染。默认情况下,TocGenerator使用KnpMenu ListRenderer类来输出HTML。

您可以将自己的ListRenderer类实例传递给TocGenerator::getHtmlMenu()。或者,您可以传递自己的渲染器(实现Knp\Menu\Renderer\RendererInterface)。

例如,您可能希望为列表项使用不同的CSS类

$someHtmlContent = '<div><h1>Test</h1><p>Lorum ipsum</p><h2>Test2</h2><p>Lorum ipsum</p></div>';


$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);

使用Twig进行自定义

KnpMenu库比默认情况下该库提供的功能更强大地集成了Twig模板系统。您可以通过使用KnpMenu附带TwigRenderer来利用它

use Knp\Menu\Matcher\Matcher;
use Knp\Menu\Renderer\TwigRenderer;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;

$someHtmlContent = '<div><h1>Test</h1><p>Lorum ipsum</p><h2>Test2</h2><p>Lorum ipsum</p></div>';

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

$twig = new Environment($twigLoader);
$itemMatcher = new Matcher();
$menuRenderer = new TwigRenderer($twig, 'knp_menu.html.twig', $itemMatcher);

$tocGenerator = new TOC\TocGenerator();

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

有序列表和无序列表

KnpMenu库默认生成无序列表(ul)。该库包含一个用于有序列表的自定义渲染器,无论您是否使用Twig

$someHtmlContent = '<div><h1>Test</h1><p>Lorum ipsum</p><h2>Test2</h2><p>Lorum ipsum</p></div>';

// Ordered List
$orderedRenderedList = (new TOC\TocGenerator())->getOrderedHtmlMenu($someHtmlContent);

Twig用法

{# Generate ordered TOC #}
{{ toc_ordered(my_content) }}

{# The same options can be used for ordered lists as unordered lists #}
{{ toc_ordered(my_content, 2, 3) }}