在AnQiCMS模板中,如何复用页头、页脚等公共模块来显示内容?

在网站建设过程中,页头、页脚、导航栏等公共模块几乎是每个页面都不可或缺的部分。如果每次都手动编写这些代码,不仅效率低下,还难以保证网站整体风格的一致性,且后续的维护工作将变得异常繁琐。AnQiCMS作为一款高效的内容管理系统,其强大的模板引擎提供了多种灵活的方式来复用这些公共模块,从而极大地提升了模板开发的效率和网站的可维护性。

AnQiCMS模板中的公共模块复用之道

首先,了解AnQiCMS模板的基本构成是关键。所有的模板文件通常存放在 /template 目录下,并以 .html 作为文件后缀。其模板语法借鉴了Django模板引擎,变量通常使用双花括号 {{变量}} 引用,而条件判断、循环控制等逻辑标签则使用 {% 标签 %}{% end标签 %} 的形式。静态资源如样式、脚本和图片则集中存放在 /public/static/ 目录中。

在AnQiCMS中,主要有三种强大且灵活的机制来实现公共模块的复用:include 标签、extends 标签(模板继承)以及 macro 标签。

1. 使用 include 标签嵌入代码片段

include 标签是最直接、最常用的模块复用方式,它允许您将一个独立的HTML代码片段插入到任何需要它的模板文件中。想象一下,网站的页头和页脚内容几乎每个页面都相同,您可以将它们分别保存为 partial/header.htmlpartial/footer.html 这样的独立文件。

例如,在您的模板主题目录下,创建一个名为 partial 的文件夹,并在其中创建 header.htmlfooter.html

partial/header.html 示例:

<header>
    <div class="logo">
        <a href="/">{% system with name="SiteLogo" %}<img src="{% system with name="SiteLogo" %}" alt="{% system with name="SiteName" %}" /></a>
    </div>
    <nav>
        <ul>
            {% navList navs %}
            {% for item in navs %}
                <li><a href="{{ item.Link }}">{{ item.Title }}</a></li>
            {% endfor %}
            {% endnavList %}
        </ul>
    </nav>
</header>

partial/footer.html 示例:

<footer>
    <p>{% system with name="SiteCopyright" %}</p>
    <p><a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">{% system with name="SiteIcp" %}</a></p>
</footer>

然后在您的主页面模板(如 index.htmlarchive/detail.html)中,只需简单地引用这些文件:

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

<main>
    <!-- 页面主体内容 -->
</main>

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

这种方式的优点在于,当您需要修改页头或页脚时,只需编辑一个文件,所有引用了该文件的页面都会自动更新。此外,include 标签还支持通过 with 关键字传递变量,甚至可以使用 only 关键字限制变量的作用域,这使得被引用的模块更加灵活。例如,{% include "partial/sidebar.html" with user_name="访客" only %} 可以向侧边栏传递特定的用户信息。为了增强模板的健壮性,您还可以使用 if_exists 关键字,确保即使被引用的模板文件不存在也不会引发错误,而是被优雅地忽略。

2. 利用 extends 标签进行模板继承

extends 标签提供了一种更强大的复用机制,它允许您定义一个基础的“骨架”模板(通常命名为 base.html),其中包含了网站所有页面共享的基本结构,如HTML文档类型、head部分、主要的布局容器等。骨架模板中通过 {% block 名称 %}{% endblock %} 定义出可被子模板重写或填充的区域。

base.html 骨架模板示例:

<!DOCTYPE html>
<html lang="{% system with name='Language' %}">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    {% block page_title %}<title>{% tdk with name="Title" siteName=true %}</title>{% endblock %}
    <link rel="stylesheet" href="{% system with name="TemplateUrl" %}/css/style.css">
    {% block page_meta %}{% tdk with name="Keywords" %}{% tdk with name="Description" %}{% endblock %}
</head>
<body>
    {% include "partial/header.html" %} {# 依然可以include公共部分 #}

    <div class="container">
        {% block main_content %}
            <!-- 默认内容,子模板可重写 -->
        {% endblock %}
    </div>

    {% include "partial/footer.html" %} {# 依然可以include公共部分 #}
    <script src="{% system with name="TemplateUrl" %}/js/main.js"></script>
    {% block page_scripts %}{% endblock %}
</body>
</html>

接下来,您的具体页面模板(如 index.html)就可以继承这个 base.html,并只关注自身独特的内容。

index.html 子模板示例:

{% extends "base.html" %}

{% block page_title %}<title>首页 - {% system with name="SiteName" %}</title>{% endblock %}

{% block main_content %}
    <section class="hero-section">
        <h1>欢迎来到AnQiCMS</h1>
        <p>您的内容管理专家</p>
    </section>
    <section class="latest-articles">
        <h2>最新文章</h2>
        <ul>
            {% archiveList archives with type="list" limit="5" %}
            {% for item in archives %}
                <li><a href="{{ item.Link }}">{{ item.Title }}</a></li>
            {% endfor %}
            {% endarchiveList %}
        </ul>
    </section>
{% endblock %}

{% block page_scripts %}
    <script>
        console.log("这是首页特有的脚本。");
    </script>
{% endblock %}

使用 extends 继承时,{% extends ... %} 必须是子模板中的第一个标签。这种方法确保了网站所有页面都遵循相同的基本布局,而页面的具体内容则在各自的 block 中定义,极大地提高了设计的一致性和开发效率。

3. 借助 macro 定义可复用函数式组件

macro 标签提供了一种类似函数的功能,您可以用它定义一段带参数的可复用代码块。当您有多个相似但参数不同的HTML组件时,macro 会非常有用,例如生成不同颜色或链接的按钮、统一风格的产品卡片等。

您可以将宏函数定义在一个独立的辅助文件(如 macro/components.html)中:

macro/components.html 示例:

{% macro render_button(text, url, css_class="btn-primary") %}
    <a href="{{ url }}" class="btn {{ css_class }}">{{ text }}</a>
{% endmacro %}

{% macro render_product_card(product) %}
    <div class="product-card">
        <img src="{{ product.Thumb }}" alt="{{ product.Title }}">
        <h3><a href="{{ product.Link }}">{{ product.Title }}</a></h3>
        <p class="price">¥{{ product.Price }}</p>
        {{ render_button("立即购买", product.Link, "btn-success") }}
    </div>
{% endmacro %}

然后在您的主模板中,通过 import 标签引入并使用这些宏:

{% import "macro/components.html" as comps %}

<section class="call-to-action">
    <h2>了解更多我们的服务</h2>
    {{ comps.render_button("点击这里", "/services", "btn-info") }}
</section>

<section class="featured-products">
    <h2>热门产品</h2>
    <div class="product-grid">
        {% archiveList products with moduleId="2" limit="3" %}
        {% for product in products %}
            {{ comps.render_product_card(product) }}
        {% endfor %}
        {% endarchiveList %}
    </div>
</section>

macro 的强大之处在于它允许您创建高度抽象和可参数化的UI组件,减少代码重复,并使模板更加简洁和富有逻辑。

###