AnQiCMS 提供了灵活强大的模板系统,让网站内容的展示既高效又美观。在模板开发中,为了提升代码的复用性和维护性,我们常常会遇到需要将一段常用的代码片段封装起来,以便在不同地方调用。这时,macro 标签就成了实现这一目标的关键工具。它允许我们定义可复用的代码块,就像编程语言中的函数一样。
为什么需要 macro 标签?
想象一下,如果您的网站有多种内容类型,比如文章列表、产品展示,它们可能在布局上有一些共同的元素,例如一个标题、一段简介和一张图片。如果每次都要重复编写这些元素的 HTML 结构,不仅效率低下,而且一旦需要修改样式或结构,就需要逐一查找并更新所有出现的地方,这无疑会带来巨大的维护成本。
macro 标签的出现正是为了解决这类问题。它允许您将这些重复的 HTML 结构连同其逻辑(例如,如何展示一个文章标题、如何格式化日期)一起封装成一个独立的、可调用的代码块。这样,您只需定义一次,便可在模板的任何地方多次调用,极大地提升了模板代码的模块化、可读性和可维护性。
如何定义一个 macro 代码块?
在 AnQiCMS 的模板中,定义 macro 的语法非常直观,它类似于定义一个函数:
{% macro macro_name(parameter1, parameter2, ...) %}
{# 这里是可复用的代码块,可以使用传入的参数 #}
{% endmacro %}
macro 标签以 {% macro ... %} 开始,以 {% endmacro %} 结束。您需要为这个 macro 指定一个唯一的名称(例如 articleItem),并在括号中列出它将接受的参数。这些参数就像函数的输入,macro 内部的代码只能访问这些参数传递进来的变量。
例如,我们来定义一个用于显示文章列表项的 macro:
{# 定义一个名为 "articleItem" 的宏,接受一个名为 "article" 的参数 #}
{% macro articleItem(article) %}
<li class="article-card">
<a href="{{ article.Link }}" title="{{ article.Title }}">
<div class="card-image">
{% if article.Thumb %}<img src="{{ article.Thumb }}" alt="{{ article.Title }}"/>{% endif %}
</div>
<h3 class="card-title">{{ article.Title }}</h3>
<p class="card-description">{{ article.Description|truncatechars:80 }}</p>
<div class="card-meta">
<time>{{ stampToDate(article.CreatedTime, "2006-01-02") }}</time>
<span>阅读量: {{ article.Views }}</span>
</div>
</a>
</li>
{% endmacro %}
在这个例子中,articleItem 宏接受一个 article 对象作为参数。在宏的内部,我们使用 article.Link、article.Title 等来访问传入文章对象的属性,并利用 truncatechars 过滤器截取描述,使用 stampToDate 格式化时间。
调用已定义的 macro 代码块
定义好 macro 后,调用它就非常简单了。在同一模板文件中,您可以通过以下方式调用:
{# 假设我们使用 archiveList 标签获取了一系列文章数据 #}
{% archiveList articles with type="list" limit="5" %}
<ul class="article-list">
{% for item in articles %}
{# 调用前面定义的 articleItem 宏,并传入当前循环的文章对象 #}
{{ articleItem(item) }}
{% endfor %}
</ul>
{% empty %}
<p>暂时没有文章内容。</p>
{% endarchiveList %}
在这里,我们在一个 for 循环中调用了 articleItem 宏,每次迭代都将当前的 item(即一篇文章对象)作为参数传递给宏。宏会按照其定义,生成对应的 HTML 结构。
跨文件复用 macro:import 的力量
对于大型项目,将所有 macro 都定义在一个文件里很快就会变得难以管理。AnQiCMS 允许您将 macro 定义在单独的文件中,并通过 import 标签将其引入到需要使用的模板里,实现真正的跨文件复用。
创建宏文件: 通常,我们会创建一个专门的目录(例如
_macros或partials/macros)来存放所有的宏文件。假设我们创建一个名为_macros/article_card.html的文件,并在其中定义上述articleItem宏:{# 文件路径: templates/your_theme/_macros/article_card.html #} {% macro articleItem(article) %} <li class="article-card"> <a href="{{ article.Link }}" title="{{ article.Title }}"> <div class="card-image"> {% if article.Thumb %}<img src="{{ article.Thumb }}" alt="{{ article.Title }}"/>{% endif %} </div> <h3 class="card-title">{{ article.Title }}</h3> <p class="card-description">{{ article.Description|truncatechars:80 }}</p> <div class="card-meta"> <time>{{ stampToDate(article.CreatedTime, "2006-01-02") }}</time> <span>阅读量: {{ article.Views }}</span> </div> </a> </li> {% endmacro %} {# 如果有其他宏,也可以一同在此文件中定义 #} {% macro productCard(product) %} <li class="product-card"> {# ... 产品卡片结构 ... #} </li> {% endmacro %}在其他模板中导入并使用: 在
index.html或其他任何需要使用这些宏的模板文件中,您可以使用import标签引入它们:{# 文件路径: templates/your_theme/index.html #} {% import "_macros/article_card.html" articleItem, productCard as myProductCardMacro %} <h1>最新文章</h1> {% archiveList articles with type="list" limit="5" %} <ul class="article-list"> {% for item in articles %} {{ articleItem(item) }} {# 调用导入的 articleItem 宏 #} {% endfor %} </ul> {% endarchiveList %} <h1>推荐产品</h1> {% archiveList products with moduleId="2" type="list" limit="3" %} <ul class="product-list"> {% for item in products %} {{ myProductCardMacro(item) }} {# 调用导入并设置别名的 productCard 宏 #} {% endfor %} </ul> {% endarchiveList %}通过
import,我们可以一次性导入一个或多个宏。使用逗号,分隔多个宏