How does a `macro` tag-defined code snippet receive and process external variables or parameters?

Secure CMS template tool:macroHow to elegantly handle external parameters passed to the label?

In AnQiCMS template development, in order to improve the reusability and maintainability of the code, we often use some auxiliary tags, and one of them is particularly powerful and worth in-depth exploration.macroThe tag is like a function in a programming language, allowing us to define reusable code snippets and customize their behavior when needed.Today, let's talk in detail about Anqi CMSmacroHow a label receives and processes external variables or parameters.

UnderstandingmacroThe core mechanism of tags

First, you need to understand.macroA tag, we can imagine it as an independent, miniaturized template function. Its biggest feature, also itsincludeessential difference in variable processing is itsStrict scope isolationThis means, amacroCode snippet does not automatically inherit any variables from the parent template it is called in, unless you explicitly pass these variables as parameters.

This design philosophy brings extremely high predictability and robustness. When you use it in a template,macroAt that time, you are very clear about what data it will handle, because all necessary data must be explicitly passed to it through the parameter list. This effectively avoids unexpected effects due to changes in the parent template context.macroThe issue of internal logic, making our template code more modular and easy to manage.

How to definemacroAnd declare parameters

Define onemacroVery intuitive, it needs a name and a pair of parentheses, within which is the list of parameters you declare to receive. These parameters are like the formal parameters of a function, beingmacroLocal variables used inside.

Let's look at a practical example, assuming we want to define one for displaying article summariesmacro:

{% macro article_summary(archive_item) %}
<div class="article-card">
    <h3><a href="{{ archive_item.Link }}">{{ archive_item.Title }}</a></h3>
    <p>{{ archive_item.Description|truncatechars:100 }}</p>
    <div class="meta">
        <span>发布日期: {{ stampToDate(archive_item.CreatedTime, "2006-01-02") }}</span>
        <span>浏览量: {{ archive_item.Views }}</span>
    </div>
</div>
{% endmacro %}

In this example,article_summaryThat's what we definemacroThe name, andarchive_itemIt is the parameter it declares to receive. InmacroWithin the internal, we can use it directlyarchive_itemThis variable, and access its various properties through the dot notation, such asarchive_item.Link/archive_item.Titleetc. Here is thearchive_itemIt is a local variable, whose value depends entirely on the data passed in during the external call.

InvokemacroPass actual parameters.

When you define one.macroAfter that, it can be called anywhere in the template. The method of calling is also simple, using double curly braces{{ }}enclosedmacroThe name, and pass the actual parameters (also known as arguments) in parentheses according to the defined order.

Continuing with the above example, suppose we go througharchiveListA label has obtained a namedrecent_articlesthe list of articles, we want to usearticle_summaryThismacroRender each article in the list:

{% archiveList recent_articles with type="list" limit="5" %}
    {% for item in recent_articles %}
        {{ article_summary(item) }} {# 这里将列表中的每个“item”作为参数传入macro #}
    {% endfor %}
{% endarchiveList %}

Here, recent_articlesover each element in the listitemRepresents a specific article data object and is passed as an argument toarticle_summaryThismacro. WhenmacroDeclared inside when it is calledarchive_itemIt will receive this oneitemThe value, thus inmacroInternal rendering of the corresponding article summary.

It is worth noting that you can pass any type of data tomacroNo matter whether it is a string, number, boolean value, or a more complex object (such as an article object, category object, etc).macroIt will process these incoming values according to your internal logic.

Modular organizationmacro: Import and alias

As the scale of the project grows, we may define multiplemacro. To better organize the code, Anqi CMS allows us tomacroDefined in a separate auxiliary template file, thenimportthe tag is introduced and used in other templates.

For example, we can create a file named_macros.htmlto store the definedarticle_summaryMacros and other possible macros are placed in it:

File:templates/default/_macros.html

{# 定义一个文章摘要的macro #}
{% macro article_summary(archive_item) %}
<div class="article-card">
    <h3><a href="{{ archive_item.Link }}">{{ archive_item.Title }}</a></h3>
    <p>{{ archive_item.Description|truncatechars:100 }}</p>
    <div class="meta">
        <span>发布日期: {{ stampToDate(archive_item.CreatedTime, "2006-01-02") }}</span>
        <span>浏览量: {{ archive_item.Views }}</span>
    </div>
</div>
{% endmacro %}

{# 假设还有其他宏,例如用于展示产品信息的宏 #}
{% macro product_card(product_item) %}
<div class="product-card">
    <h4>{{ product_item.Title }}</h4>
    <img src="{{ product_item.Logo }}" alt="{{ product_item.Title }}" />
    <p>价格: {{ product_item.Price }}</p>
</div>
{% endmacro %}

Then in your main template (for example)index.html), you can useimportTags to include these macros:

File:templates/default/index.html

{% import "_macros.html" article_summary, product_card as pc %} {# 引入article_summary和product_card,并给product_card设置别名pc #}

<section class="latest-articles">
    <h2>最新文章</h2>
    {% archiveList latest_posts with type="list" limit="3" %}
        {% for post in latest_posts %}
            {{ article_summary(post) }} {# 使用引入的macro #}
        {% endfor %}
    {% endarchiveList %}
</section>

<section class="featured-products">
    <h2>精选产品</h2>
    {% archiveList featured_products with moduleId=2 type="list" limit="2" %} {# 假设moduleId=2是产品模型 #}
        {% for product in featured_products %}
            {{ pc(product) }} {# 使用带别名的macro #}
        {% endfor %}
    {% endarchiveList %}
</section>

ByimportTags, we can optionally include the requiredmacroeven to set aliases (such asproduct_card as pc), which further enhances the neatness and readability of the template code. This way, no matter how complex the structure of your website content is, throughmacroThe parameterization and modularization capabilities can maintain the clarity and efficiency of template code.

macroThe operational value brought by the tag

From the perspective of website operation, proficiently usingmacroWhat does the tag mean:

  • Improve content update efficiency:No matter how the front page layout is adjusted, the core content displayed:macroThe logic remains unchanged. Operations personnel only need to focus on content entry and do not need to worry about the underlying code of the page display.
  • Optimize SEO strategy:Can encapsulate SEO-related metadata (such as Schema.org structured data) inmacroto ensure consistent application across different content types, reducing omissions and errors.
  • A/B testing convenient:If you want to test the display effect of different content blocks, just adjustmacroInternal logic or pass different parameters, no need to modify a lot of repetitive code.
  • Team collaboration:Template developers can focus on creating high-performance, semantically structuredmacroContent operators can take advantage of thesemacroEfficiently fill and manage content, clear division of labor, and improve collaboration efficiency.

In summary, of Anqi CMS'smacroThe label brings a functional programming experience to template development through its explicit parameter passing mechanism and strict scope management.It not only makes the template code more tidy and reusable, but more importantly, it provides strong flexibility and controllability for website content operations, and is an indispensable tool for building efficient and scalable secure CMS websites.


Frequently Asked Questions (FAQ)

1.macroTags andincludeWhat is different in variable processing for tags?The main difference is in scope.includeBy default, tags inherit all variable contexts from the parent template unless you explicitly use them.onlyKeywords are used to limit it. WhilemacroTags are exactly the opposite; they do not inherit any variables from parent templates and can only access variables explicitly passed through their parameter list. This design makesmacroThe code is more independent and predictable.

2. Can ImacroDo you want to access the global configuration information of the website internally? For example, the website nameSiteName?NomacroInternally, it is not possible to directly access the global template