如何在 AnQiCMS 模板中引入其他模板文件(如公共 header/footer)?

在 AnQiCMS 的日常运营中,高效的内容管理不仅体现在后台的数据处理,更离不开灵活的前端模板设计。对于网站运营人员来说,将公共部分(如导航栏、页脚、侧边栏等)抽离出来独立管理,并通过统一的方式引入到各个页面,是提升工作效率、保持网站一致性和简化维护的关键。AnQiCMS 提供了强大且直观的模板引入机制,让这一过程变得轻而易举。

AnQiCMS 的模板系统基于 Go 语言,并借鉴了 Django 模板引擎的语法,对模板开发者和运营人员都非常友好。所有的模板文件都使用 .html 作为后缀,并统一存放在 /template 目录下。模板所需的样式、JavaScript 脚本、图片等静态资源,则独立归集到 /public/static/ 目录,清晰的分离有助于内容的组织与管理。

模板结构与公共部分约定

AnQiCMS 鼓励模板的模块化设计。在模板的根目录下,每个模板都需要有自己的独立文件夹。在这些文件夹内部,为了便于管理和复用,有一些基本的约定:

  • 公共代码文件(bash.html:页头(header)、页脚(footer)等几乎每个页面都需要继承或引用的通用部分,通常会放在一个名为 bash.html 的文件中。这个文件可以作为网站的基础骨架,其他页面在此基础上进行扩展。
  • 代码片段目录(partial/:一些较小的、可复用的代码片段,例如侧边栏内容、面包屑导航、广告位等,可以集中存放在 partial/ 目录下。当需要这些片段时,只需简单引入即可。

这种结构确保了模板的清晰度和可维护性,使得在大型网站或多站点管理中调整公共元素变得简单高效。

核心机制:模板的引入与复用

AnQiCMS 提供了多种标签来实现模板文件的引入、继承和代码复用,最常用的包括 includeextendsmacro

使用 include 标签引入公共代码片段

include 标签是最直接的代码片段复用方式。它允许您将一个 HTML 文件内容插入到另一个 HTML 文件的指定位置。这对于引入页面的公共部分,如头部导航、底部版权信息等,非常有效。

基本用法是将目标模板文件的路径放在双引号中:

{% include "partial/header.html" %}
{% include "partial/footer.html" %}

假设您的 partial 目录下有一个 header.html 文件,其中包含了网站的顶部导航和Logo等元素,那么在任何页面模板中,您都可以用上述方式将其引入。

为了增强模板的健壮性,您可以使用 if_exists 参数。当引入的模板文件可能不存在时,使用 if_exists 可以防止页面报错,系统会直接忽略该引入:

{% include "partial/header.html" if_exists %}

include 标签还支持通过 with 参数向被引入的模板传递变量。这使得被引入的片段能够根据调用它的页面上下文显示不同的内容:

{% include "partial/header.html" with title="这是声明给header使用的title" keywords="这是声明给header使用的keywords" %}

header.html 模板中,您就可以使用 {{title}}{{keywords}} 来获取这些值。

如果您希望被引入的模板只能访问通过 with 显式传递的变量,而不继承当前模板的所有变量,可以使用 only 参数:

{% include "partial/header.html" with title="这是声明给header使用的title" keywords="这是声明给header使用的keywords" only %}

利用 extends 标签实现模板继承

extends 标签用于构建一个父子模板结构,它更适合定义页面的整体布局或“骨架”。通过一个基础的布局模板(通常称为 base.html),您可以定义页面的通用结构,并通过 block 标签标记出可变动的区域。子模板再继承这个基础模板,并选择性地覆盖这些 block 区域。

一个典型的 base.html 可能包含以下结构:

<!DOCTYPE html>
<html lang="{% system with name='Language' %}">
<head>
    <meta charset="UTF-8">
    {% block title %}<title>{% tdk with name='Title' %}</title>{% endblock %}
    <link rel="stylesheet" href="{% system with name='TemplateUrl' %}/css/style.css">
    {# 可以在这里引入公共的header片段 #}
    {% include "partial/top_header.html" %}
</head>
<body>
    <div id="wrapper">
        <header>
            {% block header_content %}
                {# 默认的头部内容,子模板可以覆盖 #}
            {% endblock %}
        </header>

        <nav>
            {% block nav_content %}
                {# 导航条内容 #}
            {% endblock %}
        </nav>

        <main id="main-content">
            {% block main_body_content %}
                {# 页面主体内容 #}
                <p>这里是默认的主体内容。</p>
            {% endblock %}
        </main>

        <footer>
            {% block footer_content %}
                {# 可以在这里引入公共的footer片段 #}
                {% include "partial/bottom_footer.html" %}
            {% endblock %}
        </footer>
    </div>
</body>
</html>

在任何需要使用这个布局的页面(如 index.htmlarchive/detail.html)中,您只需通过 {% extends 'base.html' %} 声明继承关系,然后重写相应的 block 即可:

{% extends 'base.html' %}

{% block title %}
    <title>我的首页 - AnQiCMS</title>
{% endblock %}

{% block main_body_content %}
    <h2>欢迎来到我的网站!</h2>
    <p>这是首页的独有内容。</p>
    {# 可以在这里引入其他片段 #}
    {% include "partial/latest_articles.html" %}
{% endblock %}

值得注意的是,extends 标签必须是模板文件中的第一个标签,否则模板继承将无法正常工作。

macro 标签定义可复用代码块

macro 标签用于定义一个可复用的代码块,类似于编程语言中的函数。它接受参数,并且只能访问这些传入的参数,这使得它非常适合创建独立的 UI 组件或重复出现的复杂 HTML 结构。

例如,您可以定义一个用于显示文章列表项的 macro

{% macro archive_item(archive) %}
<li class="article-list-item">
    <a href="{{ archive.Link }}" class="item-link">
        <img src="{{ archive.Thumb }}" alt="{{ archive.Title }}" class="item-thumbnail">
        <h3 class="item-title">{{ archive.Title }}</h3>
        <p class="item-description">{{ archive.Description }}</p>
    </a>
</li>
{% endmacro %}

然后,在您的页面模板中,您可以这样使用这个 macro

{% import "macros/archive.macro" archive_item %} {# 假设宏定义在 macros/archive.macro 文件中 #}

<ul>
{% for item in archives %}
    {{ archive_item(item) }}
{% endfor %}
</ul>

通过 import 语句,您可以从外部文件引入一个或多个 macro。多个宏可以用逗号隔开,也可以使用 as 关键字为宏设置别名。

模板组织与**实践

AnQiCMS 提供了“文件夹组织模式”和“扁平化文件组织模式”两种方式来组织模板文件。无论选择哪种模式,将公共的页头、页脚、侧边栏等元素独立出来并存放在 partial/ 目录下,都是一个良好的实践。

  • 页头 (partial/header.htmlbash.html):包含 <head> 区域的公共 <meta> 标签、<link> 样式引用、<script> 脚本引用,以及页面顶部的导航栏、Logo 等。
  • 页脚 (partial/footer.htmlbash.html):包含版权信息、备案号、友情链接、统计代码等。
  • 侧边栏 (partial/sidebar.html):包含热门文章、最新评论、广告等动态内容。

通过这些机制,网站运营人员可以轻松地维护网站的公共部分,确保品牌形象和用户体验的一致性,同时也大大减少了模板修改和更新的工作量。

总结

在 AnQiCMS 中,模板的模块化设计和复用机制是提升网站运营效率的强大工具。通过灵活运用 include 引入代码片段,extends 构建页面布局,以及 macro 创建可复用组件,您可以构建出结构清晰、易于维护且功能丰富的网站。这不仅简化了内容发布和页面优化工作,也为快速响应读者需求和网站迭代提供了坚实基础。

常见问题 (FAQ)

Q1: 我修改了 header.html 文件,但是网站页面上没有更新,这是怎么回事? A1: AnQiCMS 为了提升性能,会对模板文件进行缓存。如果您在修改模板文件后没有看到立即生效,通常需要清除系统缓存。您可以在 AnQiCMS 后台的“更新缓存”功能中手动清除缓存。此外,浏览器缓存也可能导致此问题,尝试强制刷新页面(Ctrl+F5 或 Cmd+Shift+R)或清除浏览器缓存。

Q2: 我想在不同页面引入同一个 partial 文件,但希望它显示不同的内容,应该怎么做? A2: 您可以使用 include 标签的 with 参数来向被引入的 partial 文件传递不同的变量。例如,如果您有一个 partial/ads.html 用于显示广告,您可以在引入时传递 ad_type 变量: {% include "partial/ads.html" with ad_type="homepage_banner" %}partial/ads.html 中,您可以通过 {% if ad_type == "homepage_banner" %} 等逻辑来显示对应的内容。

Q3: extendsinclude 有什么区别,我应该在什么时候使用它们? A3: extends 主要用于建立模板的继承关系,定义页面的整体“骨架”或“母版”。一个页面通常只能 extends 一个父模板,并在父模板定义的 block 区域内填充自己的内容。它适合定义页面的整体布局、导航、页脚等公共结构。 include 则更侧重于将小的、独立的、可复用的代码片段插入到任何模板的任何位置。一个模板可以 include 多个文件,且没有继承关系。它适合引入侧边栏、评论区、广告位、版权信息等局部模块。简而言之,extends 定义页面结构,include 填充页面内容块。