How to define and call the `macro` tag in AnQiCMS template to display reusable code blocks?

AnQiCMS provides a flexible and powerful template system that allows the display of website content to be both efficient and beautiful.In template development, in order to improve code reuse and maintainability, we often encounter the need to encapsulate a frequently used code snippet for calling in different places.macroLabels become the key tools to achieve this goal. They allow us to define reusable code blocks, just like functions in programming languages.

Why is it neededmacroTag?

Imagine if your website has multiple content types, such as article lists, product showcases, which may have some common elements in layout, such as a title, a brief introduction, and an image.If you have to rewrite the HTML structure of these elements each time, it is not only inefficient, but also once you need to modify the style or structure, you have to search and update all the places one by one, which undoubtedly brings huge maintenance costs.

macroThe appearance of tags is to solve such problems.It allows you to encapsulate these repeated HTML structures along with their logic (such as how to display an article title, how to format dates) into an independent, callable code block.This allows you to define it once and then call it multiple times anywhere in the template, greatly enhancing the modularity, readability, and maintainability of the template code.

How do you define amacrocode block?

In AnQiCMS templates, definemacrothe syntax is very intuitive, it is similar to defining a function:

{% macro macro_name(parameter1, parameter2, ...) %}
    {# 这里是可复用的代码块,可以使用传入的参数 #}
{% endmacro %}

macrotags to{% macro ... %}and ends with{% endmacro %}End. You need to specify a unique name for thismacrosuch asarticleItem), and list the parameters it will accept. These parameters are like the inputs of a function.macroThe internal code can only access the variables passed in by these parameters.

For example, let's define a macro for displaying article list items.macro:

{# 定义一个名为 "articleItem" 的宏,接受一个名为 "article" 的参数 #}
{% macro articleItem(article) %}
    <li class="article-card">
        <a href="{{ article.Link }}" title="{{ article.Title }}">
            <div class="card-image">
                {% if article.Thumb %}<img src="{{ article.Thumb }}" alt="{{ article.Title }}"/>{% endif %}
            </div>
            <h3 class="card-title">{{ article.Title }}</h3>
            <p class="card-description">{{ article.Description|truncatechars:80 }}</p>
            <div class="card-meta">
                <time>{{ stampToDate(article.CreatedTime, "2006-01-02") }}</time>
                <span>阅读量: {{ article.Views }}</span>
            </div>
        </a>
    </li>
{% endmacro %}

In this example,articleItemThe macro accepts onearticleobject as a parameter. Inside the macro, we usearticle.Link/article.Titleto access the properties of the passed article object, and usetruncatecharsUse to filter the descriptionstampToDateFormat the time.

Call the definedmacroCode block

DefinedmacroAfter that, calling it is very simple. You can call it in the same template file by the following method:

{# 假设我们使用 archiveList 标签获取了一系列文章数据 #}
{% archiveList articles with type="list" limit="5" %}
    <ul class="article-list">
    {% for item in articles %}
        {# 调用前面定义的 articleItem 宏,并传入当前循环的文章对象 #}
        {{ articleItem(item) }}
    {% endfor %}
    </ul>
{% empty %}
    <p>暂时没有文章内容。</p>
{% endarchiveList %}

Here, we are in aforloop, we called aarticleItemmacro, each iteration will take the currentitem(That is, an article object is passed as a parameter to the macro. The macro will generate the corresponding HTML structure according to its definition.)

Cross-file reusemacro:importpower

For large projects, all themacroAll defined in one file will soon become difficult to manage. AnQiCMS allows you tomacrodefined in separate files and throughimportTag it to the template where it needs to be used, achieving true file reuse across files.

  1. Create a macro file: Generally, we would create a dedicated directory (such as_macrosorpartials/macros) to store all macro files. Suppose we create a file named_macros/article_card.htmland define the abovearticleItemmacro:

    {# 文件路径: templates/your_theme/_macros/article_card.html #}
    {% macro articleItem(article) %}
        <li class="article-card">
            <a href="{{ article.Link }}" title="{{ article.Title }}">
                <div class="card-image">
                    {% if article.Thumb %}<img src="{{ article.Thumb }}" alt="{{ article.Title }}"/>{% endif %}
                </div>
                <h3 class="card-title">{{ article.Title }}</h3>
                <p class="card-description">{{ article.Description|truncatechars:80 }}</p>
                <div class="card-meta">
                    <time>{{ stampToDate(article.CreatedTime, "2006-01-02") }}</time>
                    <span>阅读量: {{ article.Views }}</span>
                </div>
            </a>
        </li>
    {% endmacro %}
    
    
    {# 如果有其他宏,也可以一同在此文件中定义 #}
    {% macro productCard(product) %}
        <li class="product-card">
            {# ... 产品卡片结构 ... #}
        </li>
    {% endmacro %}
    
  2. in other templates and use: Inindex.htmlOr any template file that needs to use these macros, you can useimportto introduce them:

    {# 文件路径: templates/your_theme/index.html #}
    {% import "_macros/article_card.html" articleItem, productCard as myProductCardMacro %}
    
    
    <h1>最新文章</h1>
    {% archiveList articles with type="list" limit="5" %}
        <ul class="article-list">
        {% for item in articles %}
            {{ articleItem(item) }} {# 调用导入的 articleItem 宏 #}
        {% endfor %}
        </ul>
    {% endarchiveList %}
    
    
    <h1>推荐产品</h1>
    {% archiveList products with moduleId="2" type="list" limit="3" %}
        <ul class="product-list">
        {% for item in products %}
            {{ myProductCardMacro(item) }} {# 调用导入并设置别名的 productCard 宏 #}
        {% endfor %}
        </ul>
    {% endarchiveList %}
    

    ByimportWe can import one or more macros at a time. Use comma,to separate multiple macros