在 AnQiCMS 的世界里,构建一个外观统一、易于管理且高效更新的网站,是每个内容运营者和开发者的共同追求。设想一下,如果网站的每个页面都需要单独设计头部、底部、侧边栏,那么当需要修改Logo、导航菜单或者版权信息时,工作量将是巨大的。幸运的是,AnQiCMS 巧妙地利用了模板继承机制,让我们能够轻松实现显示风格的统一,同时保持内容的灵活更新。
这就像是为你的网站设计了一套精美的“母版”——一个包含所有公共元素和基本布局的骨架。然后,你只需在这个骨架上填充每个页面独有的内容,就能确保整个网站看起来协调一致。AnQiCMS 采用类似 Django 模板引擎的语法,其中的 extends 和 block 标签正是实现这一魔法的关键。
搭建你的网站“母版”:extends 的基石
首先,我们需要创建一个基础的母版模板,通常我们会将其命名为 base.html,并放置在你的模板目录(/template/你的模板目录/)下。这个 base.html 文件将承载网站所有页面的共同结构,比如 HTML 的基本骨架、引入的 CSS 样式、JavaScript 脚本、Logo、主导航、页脚版权信息等等。
在这个母版中,你需要定义一些“插槽”,这些插槽就是将来子页面可以填充或重写内容的区域。我们使用 block 标签来定义这些插槽。
举个例子,一个简化的 base.html 可能看起来像这样:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
{# 这里定义页面的标题,子模板可以重写 #}
{% block title %}
<title>{% system with name="SiteName" %} - 您的网站标题</title>
{% endblock %}
<meta name="keywords" content="{% tdk with name="Keywords" %}">
<meta name="description" content="{% tdk with name="Description" %}">
{# 引入全局CSS样式 #}
<link rel="stylesheet" href="{% system with name="TemplateUrl" %}/css/style.css">
{% block head_extra %}{# 预留给子模板添加额外head内容 #}{% endblock %}
</head>
<body>
<header class="main-header">
<div class="logo">
<a href="{% system with name="BaseUrl" %}">
<img src="{% system with name="SiteLogo" %}" alt="{% system with name="SiteName" %}">
</a>
</div>
<nav class="main-nav">
{# 主导航通常放在这里 #}
{% navList navs %}
<ul>
{%- for item in navs %}
<li class="{% if item.IsCurrent %}active{% endif %}">
<a href="{{ item.Link }}">{{item.Title}}</a>
{%- if item.NavList %}
<dl>
{%- for inner in item.NavList %}
<dd><a href="{{ inner.Link }}">{{inner.Title}}</a></dd>
{% endfor %}
</dl>
{% endif %}
</li>
{% endfor %}
</ul>
{% endnavList %}
</nav>
</header>
<div class="main-content-wrapper">
<aside class="sidebar">
{% block sidebar %}{# 侧边栏内容 #}{% endblock %}
</aside>
<main class="page-content">
{# 这是核心内容区域,每个子页面都会重写这里 #}
{% block content %}
<p>这里是母版默认内容,如果子模板不重写,就会显示。</p>
{% endblock %}
</main>
</div>
<footer class="main-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>
{# 引入全局JS脚本 #}
<script src="{% system with name="TemplateUrl" %}/js/main.js"></script>
{% block body_extra %}{# 预留给子模板添加额外body末尾内容 #}{% endblock %}
</body>
</html>
可以看到,base.html 定义了页面的整体布局,并且通过 {% block title %}、{% block sidebar %}、{% block content %} 等标签,为不同的区域预留了可重写的位置。即使子模板不重写这些 block,它们也会显示 base.html 中定义的默认内容。
子页面:引用母版与重写内容
现在,我们有了网站的“母版”。接下来,当你要创建像首页、文章详情页、产品列表页这样的具体页面时,就不需要重复编写头部和底部了,只需引用这个 base.html,然后重写你需要改变的 block 区域。
引用母版
在你的子模板文件(例如 index.html、archive/detail.html 或 category/list.html)中,你需要做的第一件事就是使用 extends 标签来声明它继承自哪个母版。
非常重要的一点是:{% extends 'base.html' %} 必须是子模板文件的第一行代码。 模板引擎需要首先知道这个文件是基于哪个母版构建的,才能正确解析后续的内容。
重写内容
在 extends 声明之后,你就可以使用与母版中相同的 block 标签名称来重写该区域的内容了。
比如,针对网站的首页 index.html,你可能希望有自定义的标题和独特的首页内容,但保留公共的头部、底部和侧边栏。你可以这样编写 index.html:
{# 必须是文件的第一行 #}
{% extends 'base.html' %}
{# 重写title block,定义首页标题 #}
{% block title %}
<title>首页 - {% system with name="SiteName" %}</title>
{% endblock %}
{# 重写content block,放置首页特有的内容 #}
{% block content %}
<h2>欢迎来到我们的网站首页!</h2>
<p>这里是首页独有的内容,包括精选文章、推荐产品等。</p>
{# 可以在这里引入其他模板片段,例如最新的文章列表 #}
{% include 'partial/latest_articles.html' %}
{% endblock %}
{# 如果首页需要额外的脚本,可以重写body_extra block #}
{% block body_extra %}
<script src="{% system with name="TemplateUrl" %}/js/index_specific.js"></script>
{% endblock %}
在这个 index.html 中,我们只重写了 title 和 content 这两个 block。对于 head_extra、sidebar 和 main-header、main-footer 等区域,由于没有重写对应的 block,模板引擎会自动使用 base.html 中定义的内容。这样,我们就实现了页面的统一风格,同时又保证了内容的灵活性。
实践:统一风格与局部创新
模板继承的强大之处在于它的分层思想。你可以为不同类型的内容(如文章详情、产品列表)创建不同的“二级母版”,这些二级母版再继承自 base.html。例如,你可以有一个 article_base.html 来定义所有文章页面的通用布局(比如固定侧边栏、评论区结构等),然后具体的文章详情页再继承 article_base.html。
在使用继承的时候,有一些小技巧可以帮助我们更好地组织模板:
- 将公共头部和底部放在
base.html中。 这是最基本的统一,确保所有页面都有相同的导航和品牌信息。 - 将可能变动的区域定义为
block。 哪怕现在看起来不会变动,预留block也是一个好习惯,以便未来扩展。 - 对于小的、可复用的组件,使用
include标签。 例如,一个“最新评论”的模块,可以在sidebarblock中使用{% include 'partial/latest_comments.html' %}来引入。这使得代码更加模块化,便于维护。 - 不要过度嵌套。 虽然 AnQiCMS 支持多级继承,但过深的继承层级可能会增加