在安企CMS的模板开发中,我们常常需要根据内容的特定属性或文本片段来动态地调整页面展示。判断一个字符串或者数组中是否包含某个特定关键词,就是实现这种动态逻辑的关键一步。AnQiCMS 强大的Django风格模板引擎和内置过滤器,让这一操作变得非常直观和高效。

核心利器:contain 过滤器

在AnQiCMS的模板系统中,最直接、最推荐用来判断字符串或数组是否包含特定关键词的工具就是contain过滤器。这个过滤器能够返回一个布尔值(TrueFalse),清晰地告诉我们目标内容中是否存在指定的关键词。

contain 过滤器的工作原理

contain过滤器会根据你传递给它的数据类型,采用不同的判断方式:

  1. 对于字符串 (String): contain过滤器会检查目标字符串中是否包含指定的子字符串。这是一个子串匹配,只要目标字符串的任何部分与关键词匹配,就会返回True
  2. 对于数组 (Array/Slice): contain过滤器会检查数组中是否存在一个完全等于指定关键词的元素。
  3. 对于键值对 (Map) 或结构体 (Struct): contain过滤器会检查该对象中是否存在一个键名(key)与指定关键词完全匹配。

如何使用 contain 过滤器?

它的基本语法非常简洁:

{{ 目标数据 | contain:"关键词" }}

通常,我们会将contain过滤器与if逻辑判断标签结合使用,以便根据判断结果执行不同的模板代码。

示例 1:判断文章标题是否包含特定词

假设我们希望在文章列表中,给标题包含“教程”二字的文档添加一个特殊的角标或样式。

{% archiveList archives with type="list" limit="10" %}
    {% for item in archives %}
    <li>
        <a href="{{item.Link}}">
            <h5>
                {{item.Title}}
                {% if item.Title|contain:"教程" %}
                    <span class="badge tutorial-badge">教程</span>
                {% endif %}
            </h5>
            <p>{{item.Description}}</p>
        </a>
    </li>
    {% endfor %}
{% endarchiveList %}

在这个例子中,item.Title 是一个字符串,|contain:"教程" 就会检查文章标题中是否含有“教程”这个词。

示例 2:判断文章标签数组是否包含特定标签

假设每篇文章都有一个Tags数组(例如:["Go", "CMS", "Web"]),我们想判断某篇文章是否被标记为“CMS”。

{% archiveDetail archive with name="Id" %} {# 假设这是当前文档的上下文 #}
{% tagList tags with itemId=archive.Id limit="10" %}
    {% set tagTitles = [] %} {# 创建一个空数组用于存放标签标题 #}
    {% for tag in tags %}
        {% set tagTitles = tagTitles|add:tag.Title %} {# 将每个标签的标题添加到数组中 #}
    {% endfor %}

    {% if tagTitles|contain:"CMS" %}
        <p>这篇文章与CMS相关!</p>
    {% else %}
        <p>这篇文章不直接包含“CMS”标签。</p>
    {% endif %}
{% endtagList %}

这里我们先通过tagList标签获取当前文章的标签,然后将标签的Title字段收集到一个名为tagTitles的数组中。最后,再使用tagTitles|contain:"CMS"来判断这个数组中是否存在完全等于“CMS”的元素。

示例 3:判断键值对或结构体中是否存在特定键名

如果你有一个数据对象(比如从archiveParams获取的自定义参数),想检查它是否包含某个键。

{% archiveParams params with sorted=false %} {# 获取无序的自定义参数map #}
    {% if params|contain:"author" %}
        <p>本文作者:{{ params.author.Value }}</p>
    {% else %}
        <p>未指定作者信息。</p>
    {% endif %}
{% endarchiveParams %}

这里params是一个键值对(Map)对象,params|contain:"author"会检查是否存在名为author的键。

进阶用法:indexcount 过滤器

除了contain过滤器,AnQiCMS还提供了indexcount过滤器,它们虽然不是直接返回布尔值,但也可以间接用来判断包含关系,并在某些特定场景下提供更多信息。

index 过滤器:获取关键词位置

index过滤器会返回关键词在目标字符串或数组中首次出现的位置(索引)。如果找不到关键词,它会返回-1。因此,我们可以通过判断返回值是否大于或等于0来确定是否包含关键词。

{{ obj | index:"关键词" }}

示例:判断文章内容是否包含特定词,并想知道它在哪里

{% archiveDetail articleContent with name="Content" %}
    {% set keywordPosition = articleContent|index:"重要信息" %}
    {% if keywordPosition >= 0 %}
        <p>文章内容中包含“重要信息”,首次出现在第 {{ keywordPosition }} 个字符处。</p>
    {% else %}
        <p>文章内容中不包含“重要信息”。</p>
    {% endif %}
{% endarchiveDetail %}

count 过滤器:计算关键词出现次数

count过滤器会返回关键词在目标字符串或数组中出现的次数。如果关键词没有出现,它会返回0。通过判断返回值是否大于0,我们也可以判断是否包含关键词。

{{ obj | count:"关键词" }}

示例:计算文章内容中某个词出现的频率

{% archiveDetail articleContent with name="Content" %}
    {% set cmsCount = articleContent|count:"CMS" %}
    {% if cmsCount > 0 %}
        <p>“CMS”在文章中出现了 {{ cmsCount }} 次。</p>
    {% else %}
        <p>文章中未提及“CMS”。</p>
    {% endif %}
{% endarchiveDetail %}

小结

在AnQiCMS的模板开发中,无论是需要简单判断字符串或数组是否包含特定关键词,还是需要获取关键词的具体位置或出现次数,内置的containindexcount过滤器都能提供灵活而强大的支持。合理运用这些工具,能够帮助我们构建更加智能和动态的网站模板,从而提升用户体验和内容展示的灵活性。


常见问题 (FAQ)

Q1: contain 过滤器在判断字符串时是否区分大小写?

A1: 是的,contain过滤器在判断字符串时是区分大小写的。例如,"AnQiCMS"|contain:"cms"会返回False,因为”cms”与”CMS”不完全匹配。如果您需要进行不区分大小写的判断,您可能需要先将目标字符串和关键词都转换为统一的大小写(例如都转为小写),然后再使用contain过滤器。

Q2: 如何判断数组中的任何一个元素是否包含某个子字符串,而不是精确匹配整个元素?

A2: contain过滤器在处理数组时,只进行元素的精确匹配。如果您想判断数组中的_任何一个_元素(例如字符串)是否包含某个子字符串,您需要结合for循环和contain过滤器来逐一检查每个元素。

例如:

{% set tags = ["Go语言", "AnQiCMS系统", "Web开发"] %}
{% set foundPartial = false %}
{% for tag in tags %}
    {% if tag|contain:"CMS" %}
        {% set foundPartial = true %}
        {% break %} {# 找到后即可跳出循环 #}
    {% endif %}
{% endfor %}

{% if foundPartial %}
    <p>数组中有元素包含“CMS”子字符串。</p>
{% else %}
    <p>数组中没有元素包含“CMS”子字符串。</p>
{% endif %}

Q3: contain 过滤器能用于判断数字是否在某个数字范围内吗?

A3: contain过滤器主要用于字符串的子串匹配或集合(数组、Map)中元素的包含判断,它不适用于判断数字是否在某个数字范围内。如果您需要判断一个数字变量是否在