在AnQiCMS中,为文章内容页自动生成并显示目录(Table of Contents, 简称TOC)不仅能显著提升用户的阅读体验,还能帮助搜索引擎更好地理解文章结构,从而对SEO产生积极影响。借助AnQiCMS强大且灵活的模板系统,实现这一功能比您想象的要简单。

AnQiCMS如何支持自动生成目录?

AnQiCMS在处理文章内容时,提供了获取文章结构化信息的能力。其核心在于archiveDetail模板标签的一个特殊字段——ContentTitles。当我们通过archiveDetail标签获取文章详情时,ContentTitles会返回一个数组,这个数组包含了文章内容中所有可识别的标题(例如H1、H2、H3等)的详细信息。

ContentTitles数组中的每个元素都是一个对象,它提供了生成TOC所需的一切数据:

  • Title: 标题的文本内容。
  • Tag: 标题对应的HTML标签类型(如”H1”、”H2”)。
  • Level: 标题的层级(如1代表H1,2代表H2)。
  • Prefix: 如果有的话,标题前的自定义前缀。

有了这些信息,我们就可以在模板中遍历它们,并动态构建出层级分明的目录结构。

实现步骤详解

要在AnQiCMS的文章内容页自动生成并显示目录,您可以遵循以下步骤:

1. 定位文章详情页模板

首先,您需要找到负责渲染文章详情内容的模板文件。通常,这会是/template/{模型table}/detail.html(例如,如果是文章模型,可能是article/detail.html)或您为特定文章自定义的模板文件。

2. 获取文章标题结构信息

在您找到的模板文件中,TOC通常会放置在文章内容的上方或侧边栏。在这里,您可以使用archiveDetail标签来获取当前文章的ContentTitles信息。这个标签会把文章内容中的所有标题提取出来,供您在模板中处理。

{% archiveDetail contentTitles with name="ContentTitles" %}

这行代码会将提取到的标题数组赋值给contentTitles这个变量,接下来我们就可以对它进行操作了。

3. 构建目录HTML结构

获取到contentTitles数组后,您可以通过循环遍历它来构建目录的HTML结构。为了实现层级效果,可以利用item.Level来创建嵌套的无序列表(<ul><li>)。

此外,为了让目录中的每个条目都能点击跳转到文章内容的对应位置,您需要为每个标题生成一个唯一的锚点ID,并将其作为目录链接的href属性。由于ContentTitles默认不会提供标题的ID,我们可以通过简单的JavaScript来动态为文章内容中的标题添加ID,并让目录链接指向这些ID。

以下是一个基本的HTML结构和生成锚点ID的思路:

”`twig

<h4>文章目录</h4>
<ul class="toc-list">
{% set current_level = 0 %}
{% set html_output = "" %}
{% for item in contentTitles %}
    {% set item_level = item.Level %}
    {% set item_title_sanitized = item.Title|replace:"[\\s\\W]+","-"|lower %} {# 简单处理标题生成ID #}

    {% if item_level > current_level %}
        {# 层级增加,开始新一层的UL #}
        {{ html_output|safe }}
        {% set html_output = "" %}
        {% for i in range(item_level - current_level) %}
            {{ html_output|safe }}
            {% set html_output = "<ul>" %}
        {% endfor %}
    {% elif item_level < current_level %}
        {# 层级减少,闭合多余的UL #}
        {% set html_output = "" %}
        {% for i in range(current_level - item_level) %}
            {{ html_output|safe }}
            {% set html_output = "</ul>" %}
        {% endfor %}
    {% endif %}

    {{ html_output|safe }}
    {% set html_output = "<li><a href=\"#" ~ item_title_sanitized ~ "\">" ~ item.Title ~ "</a></li>" %}
    {% set current_level = item_level %}
{% endfor %}

{{ html_output|safe }} {# 输出最后一个li #}

{% for i in range(current_level) %}
    </ul>
{% endfor %}
</ul>