In the template development of Anqi CMS, we often need to handle the display of dynamic lists. Whether it's an article list, product showcase, or other content blocks, in order to achieve more refined style control, JavaScript interaction, or ensure the uniqueness of page elements, we need to dynamically generate a unique item for each list.idorclassProperties become particularly important. Today, let's talk about how to utilize the AnQiCMS.for巧妙利用 in a loop.addAchieve this goal with the help of filters.
Understand the requirements for dynamically generated properties.
Imagine you are building a dynamic page to display multiple articles. Each article may require an independentidso that JavaScript can accurately control its expand/collapse state, or provide a unique hook for CSS customization. If theseidorclassCannot be generated automatically, but requires manual maintenance. For a large amount of content, this will be a tedious and error-prone task.AnQiCMS powerful Django template engine syntax, providing us with a concise and efficient solution.
One of the core tools:forloop.Counter
InforIn the loop, AnQiCMS provides several special built-in variables to help us track the state of the loop. Among which,forloop.CounterIt is a very practical variable that returns the current iteration count of the loop, starting from 1.
For example, if you are iterating over a list of articles:
{% archiveList archives with type="list" limit="5" %}
{% for item in archives %}
<div class="article-item">
<p>这是第 {{ forloop.Counter }} 篇文章:{{ item.Title }}</p>
</div>
{% endfor %}
{% endarchiveList %}
This code will output: This is the 1st article: Article Title A This is the 2nd article: Article Title B ...and so on.
forloop.CounterThis provides the foundation for generating unique numbers.
The second core tool:addFilter
AnQiCMS's template filters are very flexible,addThe filter is one of the functions that can help us achieve string concatenation or numeric addition.It can add two numbers or strings together, even if the types are different, AnQiCMS will try to intelligently convert them.
For example, if you want to concatenate a number and a string:
{{ 5 | add:"CMS" }} {# 输出:5CMS #}
{{ "安企" | add:"CMS" }} {# 输出:安企CMS #}
It is this ability to intelligently concatenate different types of data that makesaddThe filter shines when generating dynamic IDs or classes.
Combined use: dynamically generate unique IDs for list items.
Now, we willforloop.CounterandaddFilter combined together, generates unique items for the list.idProperty. Assume we want each article item to have a similar.article-id-1/article-id-2Suchid:
{% archiveList archives with type="list" limit="5" %}
{% for item in archives %}
{# 使用forloop.Counter和add过滤器生成唯一ID #}
<div id="article-id-{{ forloop.Counter | add:'' }}" class="article-item">
<h3>{{ item.Title }}</h3>
<p>{{ item.Description }}</p>
</div>
{% endfor %}
{% endarchiveList %}
Here,forloop.CounterProvide a number that increments each loop. We use| add:''(Add an empty string to the value of)forloop.Counterto ensure that even if)forloop.Counteris treated as a number by the template engine, the result will be forced to be converted to a string, thus matching the prefixarticle-id-Properly concatenated. As a result, the generated HTML code will be:
<div id="article-id-1" class="article-item">...</div>
<div id="article-id-2" class="article-item">...</div>
<!-- ...以此类推 -->
This method is very suitable for scenarios that require generating unique IDs based on the order of a list.
Pursuing a unique 'stability': combining content ID
Althoughforloop.CounterCan ensure that each loop's ID is unique, but if the list's sorting changes, the same content item'sidMay vary. In some cases, you might want toidBound permanently to the content itself, does not change with the order of the list. At this point, we can use AnQiCMS content data (such as article ID)item.Id) to generate a more stable unique ID:
{% archiveList archives with type="list" limit="5" %}
{% for item in archives %}
{# 结合文章的实际ID生成唯一ID #}
<div id="article-{{ item.Id }}" class="article-item">
<h3>{{ item.Title }}</h3>
<p>{{ item.Description }}</p>
</div>
{% endfor %}
{% endarchiveList %}
The generated HTML will be:
<div id="article-101" class="article-item">...</div>
<div id="article-105" class="article-item">...</div>
<!-- 这里的数字取决于实际的文章ID -->
The ID generated in this way has stronger persistence, regardless of how the article is sorted in the list,idit remains unchanged.
To dynamically generate a unique Class for list items
The same logic also applies to dynamic generationclassalthough properties.classProperties are usually used for grouping styles, but sometimes you may need to add a unique class name based on the order or ID of each list item, for specific JavaScript selectors or fine-tuning styles.
{% archiveList archives with type="list" limit="5" %}
{% for item in archives %}
{# 结合forloop.Counter生成动态class #}
<div class="article-item article-seq-{{ forloop.Counter | add:'' }}">
<h3>{{ item.Title }}</h3>
<p>{{ item.Description }}</p>
</div>
{% endfor %}
{% endarchiveList %}
The generated HTML will be:
<div class="article-item article-seq-1">...</div>
<div class="article-item article-seq-2">...</div>
<!-- ...以此类推 -->
You can also use it like generating an ID,item.Idto generate dynamic class names.
Summary and Application
PassforIn the loopforloop.Counterandaddcombined with filters, or directly using the unique ID of the content item itself (such asitem.IdYou can easily generate unique dynamic list items in AnQiCMS templates.idorclassProperty.This greatly improves the reusability and maintainability of the template, and also provides powerful tools for front-end developers to implement richer, more precise interaction and style control.Whether it's implementing an accordion effect, a picture gallery popup, or click highlight functions, mastering this skill can make your website content operation and technical implementation more intuitive.
Common Questions (FAQ)
Q1: Why do you need to addadda filter''(empty string) directly? Isn't it{{ forloop.Counter }}ok?A1:forloop.CounterThe output itself is a number. Although in most cases, template engines will intelligently convert numbers to strings when concatenating with string literals (such as"article-id-"), it is explicit to use|add:''(Adding an empty string to a number) is a good habit to ensure type conversion.It explicitly tells the template engine that you want to perform string concatenation, especially in certain versions of template engines or specific contexts, which can avoid potential type mismatch errors and make the code more robust.
Q2: Besidesforloop.Counteranditem.IdWhat other variables can I use to generate a unique ID or Class?A2: You can use any of the following inforVariables available in the loop and guaranteed to be unique. For example, if your content model includes a timestamp field (such asitem.CreatedTime), you can combinestampToDateThe filter formats it into a unique date-time string, then withaddThe filter concatenates. But please note, ensure that these variables indeed provide enough uniqueness in your specific list,item.IdIt is usually the most recommended option for persistent unique IDs.
Q3: If I want a cyclic class name, likeoddandeven, or such repeated class names as red, blue, green,addIs a filter a **choice?A3: For such repetitive class names, AnQiCMS provides more professionalcycleLabel.cycleTags can output a preset series of values in order during each loop. For example,.{% cycle "odd" "even" %}will alternate output during each iteration.oddandevenTherefore, for such needs, using thecycletag will be more appropriate thanaddThe filter is more concise and efficient.addThe filter is more suitable for generating truly 'unique' IDs or Classes based on numbers.