在构建网站时,我们经常会遇到需要从一堆内容中挑选出最特别的一个,比如显示最新的文章作为头条,或者突出某个热门产品。在 AnQiCMS 的模板里,灵活地获取列表的第一个或最后一个元素是实现这些需求的关键。幸运的是,AnQiCMS 提供了多种直观且高效的方法来处理这些场景,让内容展示更加生动。
AnQiCMS 的模板系统采用了类似 Django 模板引擎的语法,这使得内容开发者可以非常便捷地进行模板制作。当我们使用 archiveList、categoryList、navList 等标签从后台获取内容列表时,它们通常会返回一个数组(或 Go 语言中的切片)对象,里面包含了我们需要展示的各个元素。接下来,我们就来探讨如何在这些列表中轻松地获取我们想要的第一个或最后一个元素。
利用循环的内置变量来动态识别
第一种方法是利用 for 循环内置的特殊变量 forloop.Counter 和 forloop.Revcounter。forloop.Counter 会在每次循环时从 1 开始递增,表示当前是第几个元素;而 forloop.Revcounter 则从列表的最后一个元素开始倒数,表示当前元素距离列表末尾还有多少个(最后一个元素 forloop.Revcounter 的值就是 1)。
这种方式特别适合您需要在遍历整个列表的同时,对第一个或最后一个元素进行特殊样式处理或展示不同信息。
例如,我们想从最新的文章列表中找出第一篇和最后一篇:
{% archiveList recentArchives with type="list" limit="5" %}
{% for item in recentArchives %}
{% if forloop.Counter == 1 %}
<div class="featured-item">✨ 热门头条:<a href="{{ item.Link }}">{{ item.Title }}</a></div>
{% elif forloop.Revcounter == 1 %}
<div class="last-item">⏳ 历史回顾:<a href="{{ item.Link }}">{{ item.Title }}</a></div>
{% else %}
<div>普通文章:<a href="{{ item.Link }}">{{ item.Title }}</a></div>
{% endif %}
{% empty %}
<p>暂时没有文章内容可供展示。</p>
{% endfor %}
{% endarchiveList %}
在这个例子中,forloop.Counter == 1 精确地指向了循环中的第一个元素,而 forloop.Revcounter == 1 则指明了最后一个元素。这种方式的优点是您可以在一次循环中完成所有元素的处理和识别,代码结构清晰。
使用 first 和 last 过滤器直接获取
当您的需求只是简单地获取列表的第一个或最后一个元素,而不必遍历整个列表时,AnQiCMS 提供了更直接的过滤器:first 和 last。这些过滤器可以直接作用于列表变量,返回您所需的那一个元素。在使用这些过滤器之前,最好先检查列表是否为空,以避免潜在的错误。
假设我们需要在页面顶部单独展示最新的产品图片和最旧的产品名称:
{% archiveList products with moduleId="2" order="id desc" limit="10" %}
{# 获取第一个(最新)产品 #}
{% set latestProduct = products|first %}
{% if latestProduct %}
<div class="highlight-product">
<img src="{{ latestProduct.Logo }}" alt="{{ latestProduct.Title }}" class="product-banner">
<h3>新品上市:{{ latestProduct.Title }}</h3>
</div>
{% endif %}
{# 获取最后一个(最旧)产品 #}
{% set oldestProduct = products|last %}
{% if oldestProduct %}
<div class="vintage-product">
<p>经典回顾:{{ oldestProduct.Title }}</p>
</div>
{% endif %}
{# 您可以继续在这里展示产品列表的其余部分 #}
{% for item in products %}
{% if item != latestProduct and item != oldestProduct %} {# 避免重复显示第一个和最后一个 #}
<div class="product-item">
<a href="{{ item.Link }}">{{ item.Title }}</a>
</div>
{% endif %}
{% empty %}
<p>没有找到任何产品。</p>
{% endfor %}
{% endarchiveList %}
这种方法更加简洁高效,尤其适合只需要提取特定一个元素进行独立展示的场景。请注意,这里我们使用了 {% set %} 标签来为获取到的元素赋值,以便在后续代码中更方便地使用。
借助 slice 过滤器进行灵活切片
如果您的场景需要更细粒度的控制,或者想获取列表中任意一段范围的元素,那么 slice 过滤器会非常有用。它允许您通过指定起始和结束索引来“切片”列表。获取第一个元素可以使用 slice: 配合起始索引,获取最后一个元素则可以使用负数索引。
需要注意的是,slice 过滤器即使只提取一个元素,其返回结果仍然是一个包含该元素的列表(数组),而不是单个元素本身。因此,您可能需要进一步配合 first 过滤器来获取其中的单个元素。
例如,我们希望展示第一个分类的 Logo,以及