如何在模板中定义和临时存储变量,以方便内容的显示和复用?

在构建网站时,我们经常会遇到需要重复显示某些信息、或者根据不同上下文灵活调整内容的情况。如果每次都硬编码,不仅效率低下,后期维护起来也相当麻烦。安企CMS(AnQiCMS)深知这一点,它的模板系统提供了多种灵活的方式,让我们可以在模板中定义和临时存储变量,从而实现内容的便捷显示和高效复用。

为什么需要在模板中定义和存储变量?

简单来说,定义变量就好像给数据起一个临时的名字。这样做的好处有很多:

  • 提高可读性: 复杂的表达式或数据路径可以被一个简单的变量名代替,让模板代码更容易理解。
  • 增强复用性: 一旦数据被存储在变量中,就可以在模板的多个位置多次引用,避免重复编写。
  • 方便内容调整: 当需要修改某个值时,只需更新变量的定义,所有引用该变量的地方都会自动更新,大大简化了维护工作。
  • 分离逻辑与展示: 虽然 AnQiCMS 的模板强调简洁,但适当的变量定义有助于将部分展示逻辑封装起来,让模板更专注于如何呈现内容。

AnQiCMS 的模板引擎支持类似 Django 和 Blade 的语法,这使得变量的定义和使用非常直观。

在模板中定义和临时存储变量的主要方式

在 AnQiCMS 模板中,我们主要有两种标签来定义和存储变量:{% set %}{% with %}

使用 {% set %} 标签进行局部变量赋值

{% set %} 标签是你在当前模板文件中定义一个新变量最直接、最常用的方式。它允许你将一个值、一个表达式的结果或者另一个变量的内容赋值给一个新的变量名。这个变量在它被定义的那个模板及其内部的任何 {% block %} 区域内都是可用的。

例如,你可能想给当前页面设置一个特定的标题,或者预先计算一个值:

{% set pageTitle = "我们的产品与服务" %}
{% set currentYear = now("2006") %}
{% set welcomeMessage = "欢迎来到 " ~ system.SiteName ~ "!" %}

<h1>{{ pageTitle }}</h1>
<p>&copy; {{ currentYear }} {{ welcomeMessage }}</p>

在这个例子中,pageTitlecurrentYearwelcomeMessage 都是临时变量,它们的值在当前模板中定义后,就可以在后续需要的地方直接通过双花括号 {{ 变量名 }} 进行引用。

使用 {% with %} 标签定义作用域变量

当你需要在某个特定的代码块内定义一组变量,并且希望这些变量的作用范围只限定在这个代码块内部时,{% with %} 标签就显得非常实用了。它提供了一个独立的变量作用域,这对于保持模板代码的整洁性和避免变量冲突非常有帮助。{% with %} 标签需要与 {% endwith %} 配对使用。

想象一下,你有一个通用的页头(header)模板片段,希望为它传递一些特定的标题和关键词:

{% with headerTitle="最新的技术动态" headerKeywords="科技新闻,前端开发,Go语言" %}
    {# 这里的变量 headerTitle 和 headerKeywords 只在 {% with %} 块内有效 #}
    <head>
        <title>{{ headerTitle }}</title>
        <meta name="keywords" content="{{ headerKeywords }}">
    </head>
{% endwith %}

{# 在 {% endwith %} 之后,headerTitle 和 headerKeywords 就不能直接访问了 #}

{% with %} 尤其适合配合其他标签使用,例如 {% include %},这将在后续内容中详细说明。

如何显示变量的内容?

无论你使用 {% set %} 还是 {% with %} 定义变量,最终目的都是为了显示它们的内容。在 AnQiCMS 的模板中,这通过双花括号 {{ 变量名 }} 的形式来实现。

如果变量本身是一个复杂的数据结构,例如一个文章对象或者一个联系方式对象,我们可以通过“点”操作符来访问其内部的属性或字段。比如,如果模板上下文有一个名为 archive 的文章对象,你可以这样获取它的标题和内容:

<h1>{{ archive.Title }}</h1>
<div class="article-content">{{ archive.Content|safe }}</div>

这里 |safe 是一个过滤器,它告诉模板引擎不要对 archive.Content 进行HTML转义,因为文章内容通常包含HTML标签,需要直接显示。

利用变量实现内容块的复用

变量的强大之处在于它们与内容复用机制的结合,这让你的网站模板更具灵活性和可维护性。

通过 {% include %} 传递变量

在实际项目中,我们常常会把页面中可复用的部分,比如导航、侧边栏或者页脚,拆分成独立的模板文件(也称为“局部模板”)。这时,{% include %} 标签就派上用场了。

更妙的是,当通过 {% include %} 引入这些局部模板时,我们可以利用 with 关键字,给它们传递特定的变量,让这些局部模板变得更加通用:

假设你有一个 _sidebar.html 的局部模板,它需要一个 currentCategory 变量来高亮显示当前分类:

{# 在 _sidebar.html 中 #}
<aside>
    <h3>分类列表</h3>
    <ul>
        {% for category in categories %}
            <li {% if category.Id == currentCategory.Id %}class="active"{% endif %}>
                <a href="{{ category.Link }}">{{ category.Title }}</a>
            </li>
        {% endfor %}
    </ul>
</aside>

然后,在主模板中,你可以这样引入它并传递变量:

{% include "_sidebar.html" with currentCategory=categoryDetail %}

这里的 categoryDetail 是当前页面的分类详情对象。通过 with 传递后,_sidebar.html 就可以使用 currentCategory 变量来渲染内容了。如果你只想传递指定的变量,而不希望局部模板访问当前主模板的所有变量,可以使用 only 关键字:

{% include "_sidebar.html" with currentCategory=categoryDetail only %}

这样,_sidebar.html 就只能访问 currentCategory 这个变量,其他变量则无法访问。

使用 {% macro %} 标签创建可复用函数

对于那些更像“函数”一样、需要接收参数来生成内容的模板片段,{% macro %} 标签是理想的选择。你可以把它想象成模板里的一个小工具,每次调用时,给它不同的输入(变量),它就能帮你生成相应的结果。这让代码高度模块化,复用性极强。

例如,你可以定义一个用于展示产品卡片的宏:

{# 在一个单独的 product_macros.html 文件中 #}
{% macro product_card(product) %}
    <div class="product-item">
        <a href="{{ product.Link }}">
            <img src="{{ product.Thumb }}" alt="{{ product.Title }}">
            <h3>{{ product.Title }}</h3>
            <p class="price">¥{{ product.Price }}</p>
        </a>
    </div>
{% endmacro %}

然后在需要使用产品卡片的地方,先导入这个宏,然后像调用函数一样传递产品数据:

”`twig {% import “product_macros.html” as products %} {# 导入宏并起别名 #}

{% for item in archiveList %}
    {{ products.product_card(item) }} {# 调用宏