In AnQi CMS template development, we often need to handle the display of dynamic lists. Whether it is an article list, product display, or other content blocks, in order to achieve more fine-grained style control, JavaScript interaction, or to ensure the uniqueness of page elements, a unique one is dynamically generated for each item in the list.idorclassProperties are particularly important. Today, let's talk about how to use it in AnQiCMS'sforloop,巧妙利用addA filter is used to achieve this goal.
Understanding the demand for dynamically generated properties
Imagine you are building a dynamic page to display multiple articles. Each article may need an independentidIn order for JavaScript to precisely control its expand/collapse state, or to provide a unique hook for CSS to customize styles. If theseidorclassIt cannot be generated automatically, but needs to be maintained manually, which will be a tedious and error-prone task for a large amount of content.A powerful Django template engine syntax of AnQiCMS provides us with a simple 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 them,forloop.CounterIt is a very practical variable, which returns the current iteration count of the loop, starting from 1.
For example, if you are traversing 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.CounterA foundation is provided for generating unique numbers.
The second core tool:addFilter
AnQiCMS template filters are very flexible,addThe filter is one of the functions that can help us achieve string concatenation or addition of numbers.It can add two numbers and strings together, even if the types are different, AnQiCMS will try to convert them intelligently.
For example, if you want to concatenate a number with a string:
{{ 5 | add:"CMS" }} {# 输出:5CMS #}
{{ "安企" | add:"CMS" }} {# 输出:安企CMS #}
It is this ability to intelligently concatenate different types of data that allowsaddThe filter shines when generating dynamic IDs or classes.
Combined use: dynamically generate a unique ID for list items.
Now, we willforloop.CounterandaddCombined with the filter, generate unique IDs for list items.idProperty.
Assuming we want each article item to have a similararticle-id-1/article-id-2such as this.id:
{% 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.Counterprovided an incrementing number for each loop. We use| add:''(Adding an empty string toforloop.Counterthe value) to ensure that evenforloop.CounterTreated as a number by the template engine, the result will also be forcibly converted to a string, thus forming a prefixarticle-id-Correct concatenation. This way, 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 the list.
Pursue a more 'stable' uniqueness: combine content ID
Althoughforloop.CounterEnsure that the ID is unique for each loop iteration, but if the sorting of the list changes, the same content item mayidbe different. In some cases, you may wantidPermanently bound to the content itself, not changing with the order of the list. At this point, we can use AnQiCMS content data (such as article IDitem.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 articles are sorted in the list, itsidwill remain unchanged.
Generate a unique Class for list items
The same logic also applies for dynamic generationclassAlthough.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 to facilitate 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.
Summarization and Application
Byforin the loopforloop.Counterandaddor directly use the unique ID of the content item itself (such asitem.Id), you can easily generate unique dynamic list items in the AnQiCMS templateidorclassProperty. This not only greatly improves the reusability and maintainability of templates, but also provides powerful tools for front-end developers to achieve richer and more precise interaction and style control.Whether it is to implement an accordion effect, a picture gallery pop-up, or click highlight functions, mastering this skill can make your website content operation and technical implementation more proficient.
Frequently Asked Questions (FAQ)
Q1: Why inaddAdd a filter after''(Empty string)? Directly{{ forloop.Counter }}Is that not possible?A1:forloop.CounterIt is a number itself. Although in most cases, a template engine will smartly convert numbers to strings when concatenated with string literals (such as"article-id-"), but explicitly using|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 a string concatenation operation, especially in certain template engine versions or specific contexts, which can avoid potential type mismatch errors and make the code more robust.
Q2: Besidesforloop.Counteranditem.IdCan I use any variable to generate a unique ID or Class?A2: You can use any variable inforA variable that is available in the loop and can guarantee uniqueness. For example, if your content model contains 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, make sure these variables in your specific list can provide enough uniqueness,item.IdIt is usually the most recommended option for persistent unique IDs.
Q3: If I want a cyclic class name, such asoddandevenor red, blue, green such repeating class names,addIs the filter a **choice?A3: For such cyclic, repetitive class names, AnQiCMS provides more professionalcycle.cycleThe tag can output a series of preset values in order during each loop. For example,{% cycle "odd" "even" %}It will alternate output during each iterationoddandevenTherefore, for such a requirement, usingcyclethe tag will be more thanaddThe filter is simpler and more efficient.addThe filter is more suitable for generating truly 'unique' IDs or Classes based on numbers.