How to traverse and display nested categories or content structures in a template?

In website operation, we often need to build complex and hierarchical content structures, such as multi-level classification navigation, product tree structure, or nested display of related articles under categories.AnQiCMS (AnQiCMS) relies on its flexible template engine and rich tag functions, making it simple and efficient to traverse and display these nested structures in templates.

The AnQi CMS template system uses a syntax similar to Django, which means you will mainly{{变量}}and control logic by{% 标签 %}to perform logical control, such as conditional judgments and loop traversals. Deep understanding{% for ... in ... %}Loop tags and the parameters and return structures of various data tags are the key to implementing complex nested displays.

Understanding loops and conditions in templates.

In AnqiCMS templates,{% for item in items %}The structure is the core of traversing list data. Each loop,itemthe variable will point to an element in the list, and you can useitem.属性名Access its internal data in the formitemMay represent a category object, you can accessitem.TitleCategory Title,item.Link(Category link) etc.

At the same time,{% if 条件 %}Tags allow you to conditionally render based on the specific state of the data, which is particularly useful when dealing with nested structures, such as determining if a category has subcategories. If the traversed list may be empty, you can also use{% empty %}Labels to provide alternative display when there is no content.

Traverse and display nested category structure

AnQi CMS providescategoryListLabels to obtain category data. The key to displaying nested categories lies in巧妙地利用parentIdParameters and the category object itselfHasChildrenProperty.

Firstly, you can get the top-level category list:

{% categoryList categories with moduleId="1" parentId="0" %}
    {# 一级分类列表 #}
    <ul>
        {% for category in categories %}
            <li>
                <a href="{{ category.Link }}">{{ category.Title }}</a>
                {# 判断当前分类是否有子分类 #}
                {% if category.HasChildren %}
                    {# 如果有子分类,则再次调用 categoryList 标签,并将其 parentId 设置为当前分类的ID #}
                    <ul>
                        {% categoryList subCategories with parentId=category.Id %}
                            {% for subCategory in subCategories %}
                                <li><a href="{{ subCategory.Link }}">{{ subCategory.Title }}</a></li>
                            {% endfor %}
                        {% endcategoryList %}
                    </ul>
                {% endif %}
            </li>
        {% endfor %}
    </ul>
{% endcategoryList %}

This code demonstrates how to recursively traverse two-level categories. For deeper nesting, you can follow the same pattern, insubCategoriesthe loop check again.subCategory.HasChildrencallcategoryList.

Display related content in nested categories

The website structure often needs to associate categories with specific content (such as articles, products). In AnqiCMS, you can associatecategoryListwith the tag andarchiveListUsing tags together, it displays the category while also showing some of the content under that category.

{% categoryList categories with moduleId="1" parentId="0" %}
    {# 遍历一级分类 #}
    {% for category in categories %}
        <div class="category-block">
            <h3><a href="{{ category.Link }}">{{ category.Title }}</a></h3>
            <ul>
                {# 在每个分类下,获取其关联的文章列表 #}
                {% archiveList articles with type="list" categoryId=category.Id limit="5" %}
                    {% for article in articles %}
                        <li>
                            <a href="{{ article.Link }}">{{ article.Title }}</a>
                            <span>{{ stampToDate(article.CreatedTime, "2006-01-02") }}</span>
                        </li>
                    {% empty %}
                        <li>该分类暂无文章。</li>
                    {% endfor %}
                {% endarchiveList %}
            </ul>
        </div>
    {% endfor %}
{% endcategoryList %}

here,archiveListTag throughcategoryId=category.IdThe parameter accurately retrieves the articles under the current looped category. You can adjust it as needed.limitParameters to control the number of articles displayed.

Use navigation lists to implement multi-level menus.

In addition to manually building category nesting, Anqi CMS'snavListThe tag is an ideal choice for building multi-level navigation menus. The tag directly returns a well-processed nested data structure, greatly simplifying the development of multi-level menus.

A multi-level navigation configured in the background can be called directly in the template:

{% navList mainNavs %}
    <ul class="main-menu">
        {% for nav in mainNavs %}
            <li {% if nav.IsCurrent %}class="active"{% endif %}>
                <a href="{{ nav.Link }}">{{ nav.Title }}</a>
                {# 判断当前导航项是否有子导航 #}
                {% if nav.NavList %}
                    <ul class="sub-menu">
                        {% for subNav in nav.NavList %}
                            <li {% if subNav.IsCurrent %}class="active"{% endif %}>
                                <a href="{{ subNav.Link }}">{{ subNav.Title }}</a>
                                {# 还可以继续检查 subNav.NavList 实现更深层次的嵌套 #}
                            </li>
                        {% endfor %}
                    </ul>
                {% endif %}
            </li>
        {% endfor %}
    </ul>
{% endnavList %}

navListreturnednavThe object hasNavListproperties that can be directly used to iterate through its child navigation items, making the construction of multi-level menus very intuitive.

Further, you can even navigate under these items, based on their associatedPageId(If the navigation item links to a category or a single page), call it againarchiveListorcategoryListto display related content:

{% navList mainNavs %}
    <ul class="main-menu">
        {% for nav in mainNavs %}
            <li>
                <a href="{{ nav.Link }}">{{ nav.Title }}</a>
                {% if nav.NavList %}
                    <ul class="sub-menu">
                        {% for subNav in nav.NavList %}
                            <li>
                                <a href="{{ subNav.Link }}">{{ subNav.Title }}</a>
                                {# 如果子导航关联的是一个分类,显示该分类下的文章 #}
                                {% if subNav.PageId > 0 %}
                                    {% archiveList articles with type="list" categoryId=subNav.PageId limit="3" %}
                                        {% if articles %}
                                            <div class="articles-in-menu">
                                                {% for article in articles %}
                                                    <p><a href="{{ article.Link }}">{{ article.Title }}</a></p>
                                                {% endfor %}
                                            </div>
                                        {% endif %}
                                    {% endarchiveList %}
                                {% endif %}
                            </li>
                        {% endfor %}
                    </ul>
                {% endif %}
            </li>
        {% endfor %}
    </ul>
{% endnavList %}

This example combines navigation, classification, and content in a clever way, creating a highly dynamic and rich information display.

Nested application of model custom fields.

In AnQi CMS, both content models and categories support custom fields.These custom fields can also include more complex, nested data structures, such as image galleries (Images).You can display these fields by iterating through them.

If the document detail page has a namedImagescustom image group field:

{% archiveDetail archiveImages with name="Images" %}
    <div class="product-gallery">
        {% for img in archiveImages %}
            <img src="{{ img }}" alt="产品图片">
        {% endfor %}
    </div>
{% endarchiveDetail %}

Similarly, if you define categories or document models in the background,ExtraParameters (for example, additional information containing multiple key-value pairs) can bearchiveParamsorcategoryDetailtraversed after retrieval:

{% archiveParams params %}
    <div class="extra-info">
        {% for item in params %}
            <p><strong>{{ item.Name }}:</strong> {{ item.Value }}</p>
        {% endfor %}
    </div>
{% endarchiveParams %}

This allows you to flexibly display custom data, whether it's simple text or complex image collections.

Summary

The Anqi CMS template engine provides powerful flexibility to handle various nested structures. By mastering{% for %}/{% if %}Label, as wellcategoryList/archiveListand `navList