During the template creation process of Anqi CMS, we often encounter the need to concatenate a field from an array (or list) queried from the database with a specific symbol to form a continuous string, for the purpose of displaying it beautifully on the page, such as connecting multiple tags (Tag) of an article or displaying all the features of a product.

The template engine of AnQi CMS supports syntax similar to Django templates, making it intuitive and flexible to handle such requirements.The core idea is to use the loop structure of the template engine to traverse the array and gradually construct the string we want during the traversal.

Understand the data structure of Anqi CMS template

In Anqi CMS, when we use things likearchiveList/tagListWhen such tags are used, they often return an array or slice containing multiple "items". Each item is typically a structure (object) that contains multiple fields such asTitle/Link/Descriptionsuch asarchiveListtags will return a list of document (archive) objects, each with its ownTitle/CreatedTimesuch properties.

We cannot directly concatenate the values of a specific property of these objects into a string, but we need to extract the values of the properties we are interested in one by one.

Core method: skillfully use loops and concatenation

To achieve this goal, we can adopt a general template concatenation strategy that combines loops, variable assignment, and string concatenation.

Step one: Traverse the array to get data

Firstly, we need a loop tag (forloop) to traverse the array obtained through the AnQi CMS tag. Assuming we start fromarchiveListObtained a set of documentsarchivesAnd we want to concatenate the titles of these documents:

{% archiveList archives with type="list" limit="5" %}
    {# 循环将在这里进行 #}
{% endarchiveList %}

Inside the loop,itemThe variable will represent each document object in the array. We can accessitem.Titlethe title of each document.

Step two: usesetand~String concatenation with operators

To build the final string, we need a variable to store the concatenated result. The Anqi CMS template engine allows us to use{% set 变量名 = 值 %}Label to define and modify variables. It also supports~operator as a string concatenation operator.

We can initialize an empty string variable before the loop starts and then append the required fields of each element inside the loop.

{% set joined_titles = "" %} {# 初始化一个空字符串变量 #}
{% archiveList archives with type="list" limit="5" %}
    {% for item in archives %}
        {# 在这里拼接标题 #}
    {% endfor %}
{% endarchiveList %}

Step three: Skillfully handle separators (usingforloop.last)

When concatenating strings, a common problem is how to add a separator between each element while avoiding an extra separator at the end. Fortunately,forA loop provides a special variable insideforloopwhich contains the current loop state information, includingforloop.lastIt is a boolean value used to determine whether the current element is the last one in the loop.

Utilizeforloop.lastWe can add a separator after each element, but skip it after the last one.

Combining the above steps, a complete concatenation example may look like this:

{# 假设我们想将最近5篇文章的标题用逗号和空格连接起来 #}
{% set article_titles_str = "" %} {# 初始化一个空字符串变量来存储拼接结果 #}

{% archiveList archives with type="list" limit="5" %}
    {% for item in archives %}
        {% set article_titles_str = article_titles_str ~ item.Title %} {# 拼接当前文章标题 #}
        {% if not forloop.last %}
            {% set article_titles_str = article_titles_str ~ ", " %} {# 如果不是最后一个,添加分隔符 #}
        {% endif %}
    {% endfor %}
{% endarchiveList %}

<p>最近文章标题汇总:{{ article_titles_str }}</p>

This code will first initializearticle_titles_strempty, then iteratearchiveseach item in the list. In each iteration, it will take the currentitemofTitlethe attribute toarticle_titles_strin. Then, it will checkforloop.last, if the currentitemIf it is not the last item in the list, a separator will be added after the title.,Finally,article_titles_strIt will contain the string connected by the specified separator of all titles.

The scenario: Use the string array directly|joinFilter

If your array is itself a simple string array (not an object array) or you have already converted an object array into a string array in some other way, then the Anq CMS template engine provides a more concise|joinfilter.

For example, if you have a custom field that stores a comma-separated string, you can use|splitthe filter to convert it into an array of strings, then use|joinFilter connected by different delimiters.

{# 假设有一个字符串:"标签A,标签B,标签C" #}
{% set raw_tags_str = "Go语言,CMS建站,网站优化,模板设计" %}
{# 使用 |split 过滤器将其切割成字符串数组 #}
{% set tags_array = raw_tags_str|split:"," %}

{# 现在,tags_array 是一个字符串数组,我们可以直接使用 |join 过滤器连接它们 #}
<p>文章关联标签:{{ tags_array|join:" | " }}</p>
{# 输出: 文章关联标签:Go语言 | CMS建站 | 网站优化 | 模板设计 #}

Please note,|joinThe filter operates directly on a list (or slice) and concatenates each element of the list.If the elements in the list are not strings, they are usually automatically converted to strings before being concatenated.But for likearchiveComplex structures like objects, directly.{{ archives|join:", " }}It is not feasible because the template engine does not know which attribute of the objects you want to connect. Therefore, the method of looping concatenation mentioned above is still the preferred choice.

Application scenarios in practice

  • Display article tags:Obtainarchive.TagsList (assumingTagsis a string array), then|joinconcatenate. If