AnQiCMS 模板中,如何使用条件判断和循环结构来动态显示内容?

在AnQiCMS模板中,动态显示内容是构建交互式和数据驱动型网站的核心。通过运用条件判断和循环结构,您可以根据不同的数据状态灵活地呈现信息,或者高效地遍历数据集来生成列表、表格等内容。AnQiCMS的模板引擎采用了类似于Django模板的语法,使得这些操作直观且易于上手。

接下来,我们将深入探讨如何在AnQiCMS模板中有效运用这些强大的工具。

一、 条件判断:灵活展现内容

条件判断结构允许您的模板根据特定条件来决定是否显示某部分内容,或者显示哪部分内容。这在处理不同用户状态、数据存在与否,或者特定页面逻辑时非常有用。

AnQiCMS模板中的条件判断通过 {% if ... %} 标签实现。其基本结构与许多编程语言类似,支持 ifelif(else if的缩写)和 else 子句。

基本用法:{% if condition %} 您可以用来检查一个变量是否存在、是否为真,或者满足某个条件。例如,在文章详情页,如果文章有缩略图,我们才显示它:

{% if archive.Thumb %}
    <img src="{{ archive.Thumb }}" alt="{{ archive.Title }}" />
{% endif %}

在这里,archive.Thumb 会被评估为布尔值,如果存在缩略图路径(非空字符串),则条件为真。

条件判断中的操作符: 您可以结合使用多种操作符来构建复杂的条件:

  • 比较操作符== (等于), != (不等于), > (大于), < (小于), >= (大于等于), <= (小于等于)。
  • 逻辑操作符and (与), or (或), not (非)。
  • 成员操作符in (检查元素是否存在于集合中)。

例如,判断文章ID是否为10:

{% if archive.Id == 10 %}
    <p>这是文档ID为10的文档。</p>
{% endif %}

判断循环中的当前项是否为列表中的第一个:

{% if forloop.Counter == 1 %}
    <span class="first-item-badge">热门</span>
{% endif %}

提供替代方案:{% if ... %}{% else %} 当条件不满足时,您可能需要显示另一段内容。这时可以使用 else

{% if archive.Content %}
    <div class="article-content">{{ archive.Content|safe }}</div>
{% else %}
    <p>抱歉,该文章内容正在撰写中,请稍后再访问。</p>
{% endif %}

|safe 过滤器在这里很重要,它告诉模板引擎不要转义文章内容中的HTML标签,从而正确渲染富文本。

多重条件判断:{% if ... %}{% elif ... %}{% else %} 如果您的逻辑需要处理多种情况,可以使用 elif

{% if user.IsVip %}
    <p>欢迎VIP会员,您可查看所有内容。</p>
{% elif user.IsLoggedIn %}
    <p>欢迎普通会员,部分高级内容需要升级VIP。</p>
{% else %}
    <p>请登录以查看更多内容。</p>
{% endif %}

上述例子中,我们假定存在 user 对象及其 IsVipIsLoggedIn 属性。

二、 循环结构:批量生成内容

循环结构是处理集合数据(如文章列表、分类列表、图片列表)的关键。通过循环,您可以避免重复编写相似的代码,让模板更简洁、更易于维护。

AnQiCMS模板中的循环结构通过 {% for ... in ... %} 标签实现。

基本用法:{% for item in collection %} 循环遍历一个集合,并在每次迭代中将当前元素赋值给 item 变量。

例如,获取最新的10篇文章并显示其标题和链接:

{% archiveList archives with type="list" limit="10" %}
    <ul>
        {% for article in archives %}
            <li><a href="{{ article.Link }}">{{ article.Title }}</a></li>
        {% endfor %}
    </ul>
{% endarchiveList %}

这里的 archiveList 是AnQiCMS内置的文档列表标签,它会将查询结果存储到 archives 变量中,供 for 循环使用。

处理空集合:{% for ... %}{% empty %} 如果循环的集合可能为空,您可以使用 empty 子句来提供一个友好的提示:

{% archiveList archives with type="list" categoryId="1" limit="5" %}
    {% for item in archives %}
        <div class="news-item">
            <h4><a href="{{ item.Link }}">{{ item.Title }}</a></h4>
            <p>{{ item.Description|truncatechars:100 }}</p> {# 使用truncatechars过滤器截断描述 #}
        </div>
    {% empty %}
        <p>当前分类下暂无文章。</p>
    {% endfor %}
{% endarchiveList %}

循环中的特殊变量:forloopfor 循环内部,模板引擎提供了一个名为 forloop 的特殊变量,它包含有关当前循环状态的信息,非常实用:

  • forloop.Counter:当前迭代的从1开始的索引(1, 2, 3…)。
  • forloop.Revcounter:当前迭代的从集合总数倒数开始的索引(…3, 2, 1)。

这些变量可以用于添加序号、为第一个或最后一个元素应用特殊样式等。

例如,为偶数行添加背景色:

{% categoryList categories with moduleId="1" parentId="0" %}
    {% for cat in categories %}
        <li class="{% if forloop.Counter is divisibleby:2 %}even-row{% else %}odd-row{% endif %}">
            <a href="{{ cat.Link }}">{{ cat.Title }}</a>
        </li>
    {% endfor %}
{% endcategoryList %}

这里 is divisibleby:2 是一个过滤器,用于判断数字是否能被2整除。

循环的修饰符:reversedsorted 您可以在 for 标签后添加 reversedsorted 关键字来改变循环的顺序:

  • {% for item in collection reversed %}:倒序遍历集合。
  • {% for item in collection sorted %}:按默认顺序(通常是ID或名称)排序后遍历。

重复模式:{% cycle ... %} 当您需要在循环中交替显示不同的值或CSS类时,cycle 标签非常方便:

{% archiveList archives with type="list" limit="5" %}
    {% for article in archives %}
        <li class="{% cycle 'list-item-odd' 'list-item-even' %}">
            <a href="{{ article.Link }}">{{ article.Title }}</a>
        </li>
    {% endfor %}
{% endarchiveList %}

这将使每篇文章的 <li> 标签交替拥有 list-item-oddlist-item-even 类。

三、 结合运用:构建复杂页面

条件判断和循环结构往往结合使用,以应对更复杂的页面逻辑和数据展示需求。

示例:带有子菜单的导航 一个常见的场景是构建多级导航菜单。只有当主菜单项拥有子菜单时,才显示子菜单:

”`twig {% navList navs %}

<ul class="main-menu">
    {% for item in navs %}
        <li class="main-menu-item {% if item.IsCurrent %}active{% endif %}">
            <a href="{{ item.Link }}">{{ item.Title }}</a>
            {% if item.NavList %} {# 检查是否存在下级导航 #}
                <ul class="sub-menu">
                    {% for subItem in item.NavList %}
                        <li class="sub-menu-item {% if subItem.IsCurrent %}active{% endif %}">
                            <a href="{{ sub