如何在模板中检查数组内是否存在特定元素?

在安企CMS的日常运营和模板定制中,我们经常会遇到需要根据数据内容来动态调整页面显示的情况。其中一个常见且实用的需求就是,在模板中判断一个数组(或列表)内是否存在某个特定的元素。这对于实现个性化推荐、条件显示内容、甚至是进行权限控制等功能都至关重要。

安企CMS采用类似Django的模板引擎语法,提供了丰富的标签和过滤器来处理数据。当我们从后端获取到一些数据集合,比如文章的标签列表、产品的图片组、或者某个自定义字段的多选值时,这些数据往往以数组的形式呈现。这时,如果我们需要根据数组中是否包含某个值来决定显示什么内容,就可以巧妙地利用内置的过滤器来实现。

核心技巧:使用 contain 过滤器

在安企CMS的模板系统中,最直接也最推荐用于检查数组内是否存在特定元素的方法,就是使用 contain 过滤器。这个过滤器功能强大且易于理解,它会判断一个字符串、数组(slice)、键值对(map)或结构体中是否包含指定的关键词或键名,并返回一个布尔值(TrueFalse)。

让我们来看一个简单的例子。假设您有一个自定义的文章功能,文章可以关联多个特性,这些特性以数组的形式存储在 article.Features 中,例如 ["多图", "置顶", "推荐"]。您希望在模板中判断当前文章是否包含“推荐”特性,以便显示一个特别的标记。

{# 假设 article 是当前文章对象,其 Features 是一个字符串数组 #}
{% set articleFeatures = '["多图", "置顶", "推荐"]'|list %}

{% if articleFeatures|contain:"推荐" %}
    <span class="badge badge-primary">编辑推荐</span>
{% else %}
    <span>普通文章</span>
{% endif %}

在这段代码中,我们首先使用 setlist 过滤器模拟了一个特性数组 articleFeatures。接着,{% if articleFeatures|contain:"推荐" %} 这行代码就是判断的核心:它调用 contain 过滤器来检查 articleFeatures 数组中是否包含字符串 “推荐”。如果包含,条件为 True,将显示“编辑推荐”徽章;否则,条件为 False,显示“普通文章”。

另一个选择:index 过滤器

除了 contain 过滤器,您也可以考虑使用 index 过滤器来达到类似的目的。index 过滤器会返回指定关键词在字符串或数组中首次出现的位置(索引),如果未找到,则返回 -1。因此,通过判断返回值是否不等于 -1,我们同样可以确认元素的存在性。

{% set articleFeatures = '["多图", "置顶", "推荐"]'|list %}

{% if articleFeatures|index:"置顶" != -1 %}
    <span class="badge badge-warning">置顶文章,位于第 {{ articleFeatures|index:"置顶"|add:1 }} 位</span>
{% else %}
    <span>未置顶</span>
{% endif %}

在这个例子中,articleFeatures|index:"置顶" 会返回“置顶”在数组中的索引(这里是 1,因为数组索引从 0 开始)。我们通过 != -1 判断它是否存在。如果存在,我们还可以额外利用 index 过滤器返回的具体位置信息,通过 |add:1 转换成更符合人类习惯的从1开始的序号。

虽然 index 过滤器也能实现存在性判断,但如果仅仅是想知道元素是否存在,contain 过滤器语义上更清晰,代码也更简洁。index 更适用于您在确认元素存在后,还需要获取其具体位置的场景。

实际应用场景示例

让我们结合安企CMS常用的标签,看看这些过滤器在实际模板中的应用:

  1. 根据文章推荐属性显示图标: 安企CMS的文章详情(archiveDetail)中通常有 Flag 字段,用于标记文章的推荐属性,例如 h 代表头条,c 代表推荐。这个 Flag 可能是一个包含多个字母的字符串,比如 "hc"。我们可以用 contain 过滤器来检查它。

    {% archiveDetail currentArticle %}
    <h1 class="article-title">{{ currentArticle.Title }}</h1>
    {% if currentArticle.Flag|contain:"h" %}
        <img src="/static/images/hot.png" alt="头条文章" title="头条文章" class="flag-icon">
    {% endif %}
    {% if currentArticle.Flag|contain:"c" %}
        <img src="/static/images/recommend.png" alt="推荐文章" title="推荐文章" class="flag-icon">
    {% endif %}
    <div class="article-content">{{ currentArticle.Content|safe }}</div>
    
  2. 产品详情页图片组的特殊处理: 假设您的产品模型有一个 Images 字段,存储产品图库的URL数组。您可能希望检查其中是否包含某个特定的宣传图片,以便在页面上进行特殊展示。 “`twig {% archiveDetail productDetail with name=“Images