如何在模板中判断条件并根据逻辑动态显示不同内容块?

在AnQiCMS中,灵活地控制网页内容的显示方式,是网站运营者打造个性化、高效率网站的关键。AnQiCMS的模板引擎提供了丰富的逻辑判断和动态内容展示能力,让我们可以根据不同的条件,智能地呈现内容,极大地提升用户体验和网站的适应性。

AnQiCMS的模板语法设计巧妙,它吸取了Django模板引擎的优点,同时又兼顾了Go语言的特性。这意味着,在模板文件中,我们通常会看到两种花括号的使用:双花括号 {{ 变量 }} 用于输出变量内容,而单花括号百分号 {% 标签 %} 则用于实现各种逻辑控制,如条件判断、循环等。理解并善用这些标签和变量,是实现模板动态化的第一步。

AnQiCMS模板中的条件判断基础

实现动态内容显示的核心在于条件判断。AnQiCMS通过 if 标签家族,为我们提供了强大的逻辑判断工具。其基本结构与许多编程语言类似:

{% if 条件 %}
    <!-- 条件为真时显示的内容 -->
{% elif 其他条件 %}
    <!-- 其他条件为真时显示的内容 -->
{% else %}
    <!-- 以上条件都不为真时显示的内容 -->
{% endif %}

在这里,“条件”可以是任何能返回布尔值(真或假)的表达式。我们可以使用常见的比较运算符,如等于 ==、不等于 !=、大于 >、小于 <、大于等于 >=、小于等于 <=。同时,逻辑运算符 andornot 以及 in 也为我们构建复杂判断提供了便利。例如,我们可以判断一个变量是否存在、是否为某个特定数值、或者一个字符串是否包含特定的关键词。

实用场景一:根据变量是否存在或有值进行显示

网站内容并非总是完整无缺,有时某些字段可能为空。为了避免页面出现空白或错误提示,我们可以先判断变量是否有值再决定是否显示相关内容。

一个常见的例子是图片显示。如果一篇文章没有设置缩略图,我们就不希望页面上出现一个破损的图片图标。此时,可以这样判断:

{% if archive.Thumb %}
    <img src="{{ archive.Thumb }}" alt="{{ archive.Title }}" />
{% else %}
    <!-- 如果没有缩略图,可以显示一个占位图或什么也不显示 -->
    <img src="/static/images/placeholder.png" alt="无图" />
{% endif %}

这里 archive.Thumb 会在有值时返回真,无值时返回假。类似地,对于文章描述 archive.Description、自定义字段等,都可以用此方法来控制显示。如果变量可能为空,但我们又希望它至少显示点什么,可以使用 default 过滤器来设置默认值,比如 {{ archive.Description|default:"暂无描述" }},这能有效避免内容空缺带来的视觉问题。

实用场景二:根据具体数值或布尔值进行判断

在导航、列表展示等场景中,我们经常需要根据ID、状态或布尔值来动态调整内容。

比如在导航菜单中,我们可能需要高亮显示当前页面对应的导航项,这时候 IsCurrent 这个布尔值就派上用场了:

{% navList navs %}
    <ul>
    {%- for item in navs %}
        <li class="{% if item.IsCurrent %}active{% endif %}">
            <a href="{{ item.Link }}">{{item.Title}}</a>
        </li>
    {% endfor %}
    </ul>
{% endnavList %}

通过 {% if item.IsCurrent %} 我们可以动态地为当前导航项添加 active 类名,实现高亮效果。

再如,当我们需要在分类列表中判断某个分类是否有子分类时,item.HasChildren 这个布尔值就能帮助我们决定是否显示二级菜单:

{% categoryList productCategories with moduleId="2" parentId="0" %}
    {% for item in productCategories %}
    <a href="{{item.Link}}">{{item.Title}}</a>
    {% if item.HasChildren %}
        <ul class="sub-category-menu">
            <!-- 显示子分类的逻辑 -->
        </ul>
    {% endif %}
    {% endfor %}
{% endcategoryList %}

结合 andor 逻辑运算符,可以构建更复杂的判断,比如判断用户是否登录 and 拥有特定权限 or 是管理员,从而显示不同的功能按钮。

实用场景三:处理列表与循环中的动态显示

列表是网站中最常见的内容组织形式之一。AnQiCMS的 for 循环标签不仅可以遍历数据,还能结合 empty 标签优雅地处理列表为空的情况:

{% archiveList archives with type="page" limit="10" %}
    {% for item in archives %}
        <!-- 显示文章内容的HTML -->
    {% empty %}
        <div>暂时没有文章内容,敬请期待!</div>
    {% endfor %}
{% endarchiveList %}

这样,当 archives 列表没有任何数据时,我们就能向用户展示友好的提示,而不是一片空白。

在循环中,我们还经常需要根据循环的次序来改变内容的样式或行为。AnQiCMS提供了 forloop.Counter(当前循环次数,从1开始)和 forloop.Revcounter(剩余循环次数,从1开始计数到0)等变量。

例如,实现奇偶行不同背景色:

{% for item in archives %}
    <li class="{% if forloop.Counter is divisibleby:2 %}even{% else %}odd{% endif %}">
        {{ item.Title }}
    </li>
{% endfor %}

这里 divisibleby 过滤器判断 forloop.Counter 是否能被2整除,从而为奇偶行添加不同的类名。

此外,cycle 标签允许我们在循环中轮流输出一系列预设的值,常用于实现颜色、图片路径的循环切换,或者在列表项之间插入不同的分隔符。

实用场景四:字符串内容的判断与操作

除了简单的存在性判断,有时我们还需要对字符串的具体内容进行更细致的检查。

比如,我们想判断文章标题 item.Title 中是否包含某个特定关键词:

{% if item.Title|contain:"AnQiCMS" %}
    <span class="highlight">推荐</span>
{% endif %}

这里 contain 过滤器可以判断字符串中是否包含指定内容。

当从后台获取的内容包含需要处理的HTML代码时,比如富文本编辑器输出的内容,我们需要使用 |safe 过滤器来确保HTML代码能被浏览器正确解析,而不是被转义成纯文本:

<div>
    {{ archive.Content|safe }}
</div>

而如果内容过长,可以使用 truncatecharstruncatewords 过滤器进行截取,并自动添加省略号。

高级技巧与**实践

  • 过滤器链式调用: 多个过滤器可以像链条一样串联起来,对变量进行多重处理,如 {{ article.Title|truncatechars:20|upper }},先截断再转大写。
  • 移除空白行: 在使用 {% if %}{% for %} 等逻辑标签时,有时会产生不必要的空白行。通过在标签的起始和结束处使用短横线 {%--%},可以有效地移除这些空白。
  • 变量定义: {% set ... %} 可以在当前模板中定义变量,而 {% with ... %} 更常用于为 include 引入的模板片段传递局部变量,保持代码的模块化和清晰。
  • 模板复用: 善用 include 标签将页眉、页脚、侧边栏等公共