对于那些内容丰富、篇幅较长的文章来说,一个清晰的目录结构或大纲就像一张导航图,能够极大地提升读者的阅读体验。它不仅帮助读者快速掌握文章脉络,还能让他们精准跳转到感兴趣的部分,从而提高内容的可读性和实用性。在 AnQiCMS 中,实现文章详情页的内容目录展示并非难事,系统内置的功能为我们提供了简洁高效的解决方案。

AnQiCMS 如何理解文章结构?

AnQiCMS 在设计之初就考虑到了内容管理的灵活性和对搜索引擎的友好性。当您在编辑器中创作文章时,无论是使用富文本编辑器设置 H1、H2、H3 等标题,还是通过 Markdown 编辑器撰写带有 #, ##, ### 标记的层级标题,AnQiCMS 都会智能地解析这些结构。

系统不会仅仅将内容视为一大段文本,而是能识别出其中的层次和逻辑。这种智能识别能力,正是我们在文章详情页生成目录的基础。AnQiCMS 内部会处理文章内容,提取出所有的标题信息,并将它们整理成一个结构化的数据列表,供模板调用。

通过 ContentTitles 标签获取目录数据

要在文章详情页显示目录,我们需要在相应的模板文件中(通常是 archive/detail.html 或自定义的文章详情模板)利用 AnQiCMS 提供的模板标签来获取这些结构化数据。这里的关键在于 archiveDetail 标签及其一个特殊的字段:ContentTitles

ContentTitles 字段专门用于返回文章内容中所有识别到的标题列表。它并不是直接的 HTML 结构,而是一个包含多个对象的数组,每个对象都代表一个标题,并提供了该标题的以下信息:

  • Title: 标题的文本内容。
  • Tag: 标题的 HTML 标签(例如 h1, h2, h3),可以帮助我们判断标题的层级。
  • Level: 标题的数字层级(例如 H1 对应 1,H2 对应 2),这对于目录的缩进和样式控制非常有用。
  • Prefix: 标题前可能存在的编号或符号(如果编辑器有生成)。

有了这些数据,我们就可以灵活地构建文章目录了。

逐步构建目录显示

接下来,我们来看看如何在文章详情模板中,利用 ContentTitles 来实际生成一个可交互的目录。

1. 定位模板文件

首先,您需要进入 AnQiCMS 的后台,在“模板设计”部分找到当前使用的模板,并定位到负责文章详情页显示的模板文件。根据模板设计规范,这通常是 template/您的模板目录/{模型table}/detail.html 或者在自定义模板设置中指定的具体文件。

2. 获取目录数据

在模板文件的适当位置(例如,文章内容侧边栏或者文章内容上方),使用 archiveDetail 标签获取 ContentTitles 数据。建议使用 if 标签进行判断,确保只有当文章内容中存在标题时才显示目录。

{%- archiveDetail contentTitles with name="ContentTitles" %}
{% if contentTitles %}
    <div class="article-outline">
        <h3>文章目录</h3>
        <ul>
        {% for item in contentTitles %}
            {# 生成唯一的锚点ID,通常基于标题内容进行简化,这里仅作简单示例 #}
            {% set anchorId = 'heading-' ~ forloop.Counter ~ '-' ~ item.Title|replace(" ", "-")|lower %}
            <li style="margin-left: {{ (item.Level - 1) * 20 }}px;">
                <a href="#{{ anchorId }}">{{ item.Prefix }}{{ item.Title }}</a>
            </li>
        {% endfor %}
        </ul>
    </div>
{% endif %}

在这段代码中:

  • 我们首先通过 {%- archiveDetail contentTitles with name="ContentTitles" %} 获取了目录数据并赋值给 contentTitles 变量。
  • {% if contentTitles %} 判断确保只有当文章存在标题时才渲染目录结构。
  • {% for item in contentTitles %} 循环遍历每一个标题。
  • {% set anchorId = 'heading-' ~ forloop.Counter ~ '-' ~ item.Title|replace(" ", "-")|lower %} 这行代码尝试为每个标题生成一个唯一的 ID。由于 AnQiCMS 的过滤器中没有直接的 slugify 功能,这里我们使用 forloop.Counter 来确保唯一性,并用 replace 简单地将空格替换为连字符并转换为小写,作为一个基本的锚点 ID 生成示例。在实际应用中,您可能需要更健壮的 JavaScript 代码来生成 HTML 标题的 ID,并保持与目录链接的一致性。
  • margin-left: {{ (item.Level - 1) * 20 }}px; 巧妙地利用 item.Level 来实现目录的层级缩进,例如 H2 标题会比 H1 标题多缩进 20 像素。
  • <a href="#{{ anchorId }}">{{ item.Prefix }}{{ item.Title }}</a> 创建了目录项,链接到文章内容中对应标题的锚点。

3. 确保文章内容标题拥有对应的锚点 ID

为了让上述目录链接能够正确跳转,文章内容中的实际 HTML