在构建网站时,我们经常会遇到需要重复显示某些信息、或者根据不同上下文灵活调整内容的情况。如果每次都硬编码,不仅效率低下,后期维护起来也相当麻烦。安企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>© {{ currentYear }} {{ welcomeMessage }}</p>
在这个例子中,pageTitle、currentYear 和 welcomeMessage 都是临时变量,它们的值在当前模板中定义后,就可以在后续需要的地方直接通过双花括号 {{ 变量名 }} 进行引用。
使用 {% 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) }} {# 调用宏