在网站建设过程中,页头、页脚、导航栏等公共模块几乎是每个页面都不可或缺的部分。如果每次都手动编写这些代码,不仅效率低下,还难以保证网站整体风格的一致性,且后续的维护工作将变得异常繁琐。AnQiCMS作为一款高效的内容管理系统,其强大的模板引擎提供了多种灵活的方式来复用这些公共模块,从而极大地提升了模板开发的效率和网站的可维护性。
AnQiCMS模板中的公共模块复用之道
首先,了解AnQiCMS模板的基本构成是关键。所有的模板文件通常存放在 /template 目录下,并以 .html 作为文件后缀。其模板语法借鉴了Django模板引擎,变量通常使用双花括号 {{变量}} 引用,而条件判断、循环控制等逻辑标签则使用 {% 标签 %} 和 {% end标签 %} 的形式。静态资源如样式、脚本和图片则集中存放在 /public/static/ 目录中。
在AnQiCMS中,主要有三种强大且灵活的机制来实现公共模块的复用:include 标签、extends 标签(模板继承)以及 macro 标签。
1. 使用 include 标签嵌入代码片段
include 标签是最直接、最常用的模块复用方式,它允许您将一个独立的HTML代码片段插入到任何需要它的模板文件中。想象一下,网站的页头和页脚内容几乎每个页面都相同,您可以将它们分别保存为 partial/header.html 和 partial/footer.html 这样的独立文件。
例如,在您的模板主题目录下,创建一个名为 partial 的文件夹,并在其中创建 header.html 和 footer.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.html 或 archive/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组件,减少代码重复,并使模板更加简洁和富有逻辑。
###