How to accurately control the count and iteration order of list loops in the template?

Overview of basic loops and iterations

First, let's start with the most basic loop tag{% for %}Start. In the AnqiCMS template, when we want to display a collection of content (such as a series of articles or products), we will usually combine sucharchiveList/categoryListorpageListsuch data tags to retrieve data, then useforloop tags to iterate over these data.

A typical example is to retrieve and display a list of articles:

{% archiveList archives with type="list" limit="10" %}
    {% for item in archives %}
        <div class="article-item">
            <h3><a href="{{item.Link}}">{{item.Title}}</a></h3>
            <p>{{item.Description}}</p>
        </div>
    {% endfor %}
{% endarchiveList %}

Here, archivesIsarchiveListthe article set returned by the tag,itemIt is the variable of each article in the loop. Understanding this basic structure is the key to precise control later.

Precisely master the loop count and position

In many scenarios, we are not just simply traversing data, but also need to know which item the current loop is on, or how many items are left until the end of the loop. Anqi CMS provides for thisforloop.Counterandforloop.RevcounterThese are very useful variables:

  • forloop.Counter: This variable will return the current loop count, from1Start incrementing. It is very suitable for displaying numbers or determining whether it is the first or second item in the list.
  • forloop.Revcounter: This variable returns how many items are left until the end of the loop, the same from1Start decreasing. It becomes particularly convenient when you need to handle the last item or the last few items in a list.

Suppose we want to add numbering to the article list and identify the second-to-last article:

{% archiveList archives with type="list" limit="10" %}
    {% for item in archives %}
        <div class="article-item {% if forloop.Revcounter == 2 %}last-second-item{% endif %}">
            <span class="index">{{forloop.Counter}}.</span>
            <h3><a href="{{item.Link}}">{{item.Title}}</a></h3>
            <p>{{item.Description}}</p>
        </div>
    {% endfor %}
{% endarchiveList %}

This code not only clearly displays the article number, but also through judgment:forloop.RevcounterThe value, added a special CSS class to the second last article for easy styling customization.

Flexibly adjust the iteration order:reversedandsorted

Sometimes, we want to traverse the data we have retrieved in a specific order. Anqi CMS'sforLoop tags supportreversedandsortedKeywords, to change the order of iteration:

  • reversed: If you want to traverse the data in reverse order, you canforadd areversed. For example, if the list is originally sorted from new to old by release time, addingreversedwill display it from old to new.
  • sorted: This keyword allows you to sort the elements in the list. It is usually more effective for lists containing sortable values (such as numbers, strings). It should be noted that for througharchiveListLabel to get the content data, we are more throughorderParameters are sorted during the data acquisition phasesortedMore suitable for general data arrays

For example, if we have a simple list of numbersmyNumbers = [5, 2, 8, 1]We can traverse like this:

{% set myNumbers = "[5,2,8,1]"|list %}
<div>
    <p>原始顺序:</p>
    {% for num in myNumbers %}
        <span>{{num}} </span>
    {% endfor %}
</div>
<div>
    <p>反转顺序:</p>
    {% for num in myNumbers reversed %}
        <span>{{num}} </span>
    {% endfor %}
</div>
<div>
    <p>排序后:</p>
    {% for num in myNumbers sorted %}
        <span>{{num}} </span>
    {% endfor %}
</div>

This will output separately:5 2 8 1/1 8 2 5and1 2 5 8.

Conditional display in the loop:ifThe clever use of tags

Nested in the loop:ifLogical judgment tag, which can achieve more detailed display control. It is very useful for highlighting specific content or changing the layout of content based on certain conditions.

Except for utilizingforloop.Counterandforloop.RevcounterTo judge items other than the first and last, we can also judge the attributes of the data items according to business requirements:

{% archiveList articles with type="list" limit="8" flag="c" %} {# 获取推荐文章 #}
    {% for article in articles %}
        {% if forloop.Counter == 1 %}
            <div class="featured-article">
                <h2><a href="{{article.Link}}">{{article.Title}}</a></h2>
                <p>这是特别推荐的第一篇文章,不容错过!</p>
            </div>
        {% elif article.Views > 1000 %}
            <div class="popular-article">
                <h4><a href="{{article.Link}}">{{article.Title}}</a></h4>
                <span>阅读量已破千!</span>
            </div>
        {% else %}
            <div class="normal-article">
                <h5><a href="{{article.Link}}">{{article.Title}}</a></h5>
            </div>
        {% endif %}
    {% endfor %}
{% endarchiveList %}

This code sets a unique style for the first article, articles with more than a thousand reads also have a separate style, and other articles are displayed in a normal style, greatly enriching the visual hierarchy of the content.

Gracefully handle empty lists:emptyTag

Sometimes, througharchiveListThe result may be empty for other labels. If not handled properly, it may cause blank or unfriendly prompts on the page.{% empty %}Labels can help us elegantly handle this situation:

{% archiveList searchResults with type="page" q=urlParams.q limit="10" %}
    {% for item in searchResults %}
        <div class="search-result-item">
            <h4><a href="{{item.Link}}">{{item.Title}}</a></h4>
            <p>{{item.Description}}</p>
        </div>
    {% empty %}
        <div class="no-results">
            <p>抱歉,没有找到您搜索的 "{{urlParams.q}}" 相关内容。</p>
            <p>您可以尝试更换关键词或浏览其他分类。</p>
        </div>
    {% endfor %}
{% endarchiveList %}

WhensearchResultsWhen the list is empty,{% empty %}the content in the block will be rendered, providing clear feedback to the user.

alternating mode in the loop:cycleTag

If you need to apply a repeated style or text pattern to each item in the list, for example, to make the background color of adjacent list items different,cycleTags are a very practical tool:

{% archiveList products with type="list" limit="6" %}
    {% for product in products %}
        <div class="product-card {% cycle 'odd-bg' 'even-bg' %}">
            <img src="{{product.Thumb}}" alt="{{product.Title}}">
            <h5><a href="{{product.Link}}">{{product.Title}}</a></h5>
        </div>
    {% endfor %}
{% endarchiveList %}

Here, {% cycle 'odd-bg' 'even-bg' %}This will output alternately in each loop'odd-bg'and'even-bg'These strings can be used as CSS class names to easily implement a zebra line effect list style.

Optimize data source: list tag parameters

Although the aforementioned method can accurately control the iteration of the loopmethodBut the real 'accurate control' often starts fromdata sourceStart. The list label of Anqi CMS (such as `