在安企CMS的模板制作过程中,我们经常会遇到需要将从数据库中查询出来的数组(或列表)中的某个字段,用特定的符号连接起来,形成一个连续的字符串,以便在页面上美观地展示,例如将一篇文章的多个标签(Tag)连接起来,或者展示某个产品的所有特性。
安企CMS的模板引擎支持类似Django模板的语法,这使得处理这类需求变得直观且灵活。核心思想是利用模板引擎的循环结构来遍历数组,并在遍历过程中逐步构建我们想要的字符串。
理解安企CMS模板中的数据结构
在安企CMS中,当我们使用像 archiveList、tagList 这样的标签时,它们返回的往往是一个包含多个“项目”(item)的数组或切片(slice)。每个“项目”通常是一个结构体(对象),其中包含了多个字段(如 Title、Link、Description 等)。例如,archiveList 标签会返回一个文档(archive)对象的列表,每个文档对象有其自身的 Title、CreatedTime 等属性。
要将这些对象中某个特定属性的值连接成字符串,我们不能直接对整个对象列表使用连接操作,而是需要逐一提取出我们感兴趣的属性值。
核心方法:巧用循环与拼接
实现这一目标,我们可以采用一种通用的模板拼接策略,它结合了循环、变量赋值和字符串连接操作。
步骤一:遍历数组获取数据
首先,我们需要一个循环标签(for 循环)来遍历通过安企CMS标签获取到的数组。假设我们从 archiveList 中获取了一组文档 archives,并且我们想连接这些文档的标题:
{% archiveList archives with type="list" limit="5" %}
{# 循环将在这里进行 #}
{% endarchiveList %}
在循环内部,item 变量会依次代表数组中的每一个文档对象。我们可以通过 item.Title 访问到每个文档的标题。
步骤二:使用 set 和 ~ 运算符拼接字符串
为了构建最终的字符串,我们需要一个变量来存储拼接的结果。安企CMS模板引擎允许我们使用 {% set 变量名 = 值 %} 标签来定义和修改变量。同时,它支持 ~ 符号作为字符串连接(concatenation)运算符。
我们可以在循环开始前初始化一个空字符串变量,然后在循环内部将每个元素的所需字段追加到这个变量上。
{% set joined_titles = "" %} {# 初始化一个空字符串变量 #}
{% archiveList archives with type="list" limit="5" %}
{% for item in archives %}
{# 在这里拼接标题 #}
{% endfor %}
{% endarchiveList %}
步骤三:巧妙处理分隔符(使用 forloop.last)
拼接字符串时,一个常见的问题是如何在每个元素之间添加分隔符,同时避免在最后一个元素后面出现多余的分隔符。幸运的是,for 循环内部提供了一个特殊的变量 forloop,它包含了当前循环状态的信息,其中 forloop.last 是一个布尔值,用于判断当前是否是循环的最后一个元素。
利用 forloop.last,我们可以在每个元素后面添加分隔符,但在最后一个元素后面跳过。
将以上所有步骤结合起来,一个完整的拼接示例可能如下:
{# 假设我们想将最近5篇文章的标题用逗号和空格连接起来 #}
{% set article_titles_str = "" %} {# 初始化一个空字符串变量来存储拼接结果 #}
{% archiveList archives with type="list" limit="5" %}
{% for item in archives %}
{% set article_titles_str = article_titles_str ~ item.Title %} {# 拼接当前文章标题 #}
{% if not forloop.last %}
{% set article_titles_str = article_titles_str ~ ", " %} {# 如果不是最后一个,添加分隔符 #}
{% endif %}
{% endfor %}
{% endarchiveList %}
<p>最近文章标题汇总:{{ article_titles_str }}</p>
这段代码会先初始化 article_titles_str 为空,然后遍历 archives 列表中的每一项。在每次循环中,它会将当前 item 的 Title 属性添加到 article_titles_str 中。随后,它会检查 forloop.last,如果当前 item 不是列表的最后一项,就会在标题后面添加一个 , 分隔符。最终,article_titles_str 将包含所有标题用指定分隔符连接而成的字符串。
更简洁的场景:直接对字符串数组使用 |join 过滤器
如果您的数组本身就是一个简单的字符串数组(而不是对象数组),或者您通过其他方式已经将对象数组转换成了字符串数组,那么安企CMS模板引擎提供了一个更简洁的 |join 过滤器。
例如,如果您有一个自定义字段存储的是一个逗号分隔的字符串,您可以使用 |split 过滤器先将其转换为字符串数组,然后再使用 |join 过滤器以不同的分隔符连接。
{# 假设有一个字符串:"标签A,标签B,标签C" #}
{% set raw_tags_str = "Go语言,CMS建站,网站优化,模板设计" %}
{# 使用 |split 过滤器将其切割成字符串数组 #}
{% set tags_array = raw_tags_str|split:"," %}
{# 现在,tags_array 是一个字符串数组,我们可以直接使用 |join 过滤器连接它们 #}
<p>文章关联标签:{{ tags_array|join:" | " }}</p>
{# 输出: 文章关联标签:Go语言 | CMS建站 | 网站优化 | 模板设计 #}
请注意,|join 过滤器直接作用于一个列表(或切片),并将列表中的每个元素连接起来。如果列表中的元素不是字符串,它们通常会被自动转换为字符串再进行连接。但对于像 archive 对象这样的复杂结构,直接 {{ archives|join:", " }} 是行不通的,因为模板引擎不知道您想连接这些对象的哪个属性。因此,对于对象数组,上述循环拼接的方法依然是首选。
实际应用场景
- 展示文章标签: 获取
archive.Tags列表(假设Tags是一个字符串数组),然后用|join连接。如果