如何在 AnQiCMS 模板中定义和使用宏函数来创建可重用的代码块?

作为一名资深的安企CMS网站运营人员,我深知内容管理系统的模板功能对于提升网站运营效率和内容展现质量至关重要。AnQiCMS强大的Django模板引擎语法,为我们提供了灵活的内容呈现能力,而其中的宏函数(Macro)功能,更是实现代码复用、简化模板结构、提高开发与维护效率的利器。

在日常的内容创作和发布过程中,我们常常会遇到一些重复性的代码片段,例如文章列表的显示格式、产品卡片的布局、导航菜单的特定结构等。如果每次都复制代码块,不仅会增加模板文件的体积,降低可读性,更会在后期修改时带来巨大的工作量和出错风险。宏函数的出现,正是为了解决这一痛点,它允许我们将这些可重用的代码逻辑封装起来,像调用函数一样在模板中灵活使用。

AnQiCMS 模板引擎与宏函数

AnQiCMS 采用类似 Django 的模板引擎语法,这一特性使得它在模板制作上非常灵活且易于上手。宏函数作为其辅助标签之一,本质上是一种带参数的模板代码片段,它拥有独立的作用域,只处理传入的参数。这与include标签有所不同,include标签会继承并使用当前模板的所有上下文变量,而宏函数则更专注于其自身接收的参数,这使得宏函数更具模块化和独立性。

定义可重用代码块:宏函数的语法

宏函数通过{% macro macro_name(参数列表) %} ... {% endmacro %}的结构进行定义。macro_name是你为宏函数起的名字,而参数列表则是宏函数运行时需要接收的变量,这些变量将在宏函数内部可见和使用。宏函数内部的逻辑可以是任意有效的模板代码,包括HTML结构、其他标签、变量输出等。

例如,我们经常需要在网站不同位置展示文章的简要信息,其结构可能包含标题、链接、描述和发布日期。我们可以为此定义一个宏函数:

{% macro render_article_item(article) %}
<li class="article-item">
    <a href="{{ article.Link }}" class="article-link">
        <h5 class="article-title">{{ article.Title }}</h5>
    </a>
    <p class="article-description">{{ article.Description|truncatechars:100 }}</p> {# 截取前100字符 #}
    <span class="article-date">{{ stampToDate(article.CreatedTime, "2006-01-02") }}</span>
</li>
{% endmacro %}

在这个render_article_item宏函数中,article是一个传入的参数,它代表着一篇具体的文章数据对象。宏函数内部通过访问article对象的LinkTitleDescriptionCreatedTime等属性,来构建文章列表项的HTML结构。我们还使用了truncatechars过滤器截取了描述文本,并用stampToDate函数格式化了时间戳,这些都是AnQiCMS模板引擎提供的强大功能。

在模板中有效利用宏函数

宏函数定义后,我们可以在模板中通过{{ macro_name(参数值) }}的语法来调用它。

在同一模板文件中使用宏函数

如果宏函数定义在当前模板文件中,可以直接在文件中任何需要的地方调用它。这适用于一些只在当前模板中多次使用的局部代码块。

{# 假设render_article_item宏函数已在当前文件顶部定义 #}

<h2>最新文章</h2>
{% archiveList latest_articles with type="list" limit="5" %}
    <ul class="latest-articles-list">
        {% for article in latest_articles %}
            {{ render_article_item(article) }} {# 直接调用宏函数并传入文章对象 #}
        {% endfor %}
    </ul>
{% empty %}
    <p>暂时没有最新文章。</p>
{% endarchiveList %}

跨模板文件导入和使用宏函数

为了更好地管理和组织宏函数,推荐将它们定义在独立的模板文件中,通常这些文件会存放在模板目录下的某个子目录中,例如partial/macros/。这样可以实现宏函数的全局复用,并且避免主模板文件过于庞大。

假设我们创建了一个名为macros/common_macros.html的文件,并在其中定义了多个通用的宏函数,例如:

文件:templates/your_template/macros/common_macros.html

{# templates/your_template/macros/common_macros.html #}

{% macro render_article_item(article) %}
<li class="article-item">
    <a href="{{ article.Link }}" class="article-link">
        <h5 class="article-title">{{ article.Title }}</h5>
    </a>
    <p class="article-description">{{ article.Description|truncatechars:100 }}</p>
    <span class="article-date">{{ stampToDate(article.CreatedTime, "2006-01-02") }}</span>
</li>
{% 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="product-price">${{ product.Price | floatformat:2 }}</p> {# 格式化价格为两位小数 #}
    <button class="add-to-cart">加入购物车</button>
</div>
{% endmacro %}

现在,在需要使用这些宏函数的任何模板文件中(例如index.htmldetail.html),我们可以使用import标签将它们导入进来。import标签的语法是{% import "文件路径" macro_name1, macro_name2 as alias_name, ... %}。其中,as关键字允许我们为导入的宏函数设置一个别名,以避免命名冲突或使用更简洁的名称。

文件:templates/your_template/index.html

”`twig {# templates/your_template/index.html #}

{% import “macros/common_macros.html” render_article_item, render_product_card as product_card_renderer %}

{% extends “base.html” %} {# 假设页面继承自base.html #}

{% block content %}

<section class="latest-news">
    <h2>最新资讯</h2>
    {% archiveList latest_articles with type="list" moduleId="1" limit="3" %} {# 假设文章模型ID为1 #}
        <ul class="latest-articles-list">
            {% for article in latest_articles %}
                {{ render_article_item(article) }} {# 调用导入的文章宏函数 #}
            {% endfor %}
        </ul>
    {% empty %}
        <p>暂无最新资讯。</p>
    {% endarchiveList %}
</section>

<section class="featured-products">
    <h2>热门产品</h2>
    <div class="featured-products-grid">
        {% archiveList featured_products with type="list" moduleId="2" limit="4" %} {# 假设产品模型ID为2 #}
            {% for product in featured_products %}