Security CMS Template Tool:macroHow can tags elegantly handle external parameters?
In AnQiCMS template development, to improve code reusability and maintainability, we often use some auxiliary tags, and one particularly powerful and worth in-depth exploration ismacroLabel.It is like a function in programming languages, allowing us to define reusable code snippets and customize their behavior by passing different parameters when needed.macroHow do tags receive and process external variables or parameters?
UnderstandingmacroThe core mechanism of the tag
First, you need to understandmacroLabels, we can imagine them as independent, miniaturized template functions. Their biggest feature, and what sets them apart fromincludeThe most essential difference between labels and variables in terms of processing isStrict scope isolationThis means thatmacroa code snippet does not automatically inherit any variables from the parent template it is called within, unless you explicitly pass these variables as arguments.
This design philosophy brings extremely high predictability and robustness. When you use it in a template,macroWhen, you are clear about it, it will handle which data, because all necessary data must be explicitly passed to it through the parameter list. This effectively avoids unexpected effects on the parent template context due to changes.macroThe issue of internal logic, making our template code more modular and easier to manage.
How to definemacroAnd declare parameters
Define amacroVery intuitive, it needs a name and a pair of parentheses, and the list of parameters you declare to receive is inside the parentheses. These parameters are like the formal parameters of a function.macroLocal variables used internally.
Let's look at a real example, assuming we want to define a function to display article summaries,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 %}
In this example,article_summarywhich is the one we definedmacroname, andarchive_itemwhich is the parameter it declares to receive. InmacroThe inside, we can directly usearchive_itemthis variable, and access its properties with a dot, such asarchive_item.Link/archive_item.Titleetc. Here,archive_itemIt is a local variable entirely, its value entirely depends on the data passed in during the external call.
Invokemacroand pass actual parameters
when you have defined amacroAfter that, it can be called anywhere in the template. The way to call it is also simple, using double curly braces{{ }}wrappedmacroName, and pass the actual parameters (also called arguments) in the order defined within parentheses.
Continuing with the previous example, suppose we get a name byarchiveListthe label.recent_articles[en] article list, we hope to usearticle_summaryThismacroto render 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_articlesin the listitem(representing a specific article data object) are passed as arguments toarticle_summaryThismacro). WhenmacroWhen called, it internally declares the parameterarchive_itemand will receive thisitemvalue, thus renderingmacrothe summary information of the corresponding article internally.
It is worth noting that you can pass any type of data in.macroThis can be a string, a number, a boolean, or even more complex objects (such as article objects, category objects, etc.).macroIt will process these incoming values based on your internal logic.
Modular organizationmacro: Import and alias
As the scale of the project grows, we may define multiplemacroIn order to better organize code, Anqi CMS allows us to putmacrodefined in a separate auxiliary template file, and thenimportintroduce and use the tag in other templates.
For example, we can create a file named_macros.htmland place the above-definedarticle_summarymacros and other possible macros 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.htmlIn【en】you can useimporttags to introduce 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>
Passimporttags, we can optionally introduce the neededmacro, and even set aliases for them (likeproduct_card as pcThis further enhances the neatness and readability of the template code. In this way, no matter how complex the structure of your website content is,macroThe parameterization and modularization capabilities can maintain the clarity and efficiency of template code.
macroThe operational value brought by tags
From the perspective of website operation, masteringmacroTags mean:
- Enhance content update efficiency:Irrespective of the adjustment of the front-end page layout,
macroThe logic remains unchanged. Operation personnel only need to focus on content entry and do not have to worry about the underlying code of the page display. - Optimize SEO strategy:The SEO-related metadata (such as Schema.org structured data) can be encapsulated in
macroto ensure consistent application across different content types, reducing omissions and errors. - A/B testing convenience:To test the display effects of different content blocks, just adjust
macrothe internal logic or pass in different parameters, without modifying a large amount of repetitive code. - Team collaboration:Template developers can focus on creating high-performance, semantically meaningful
macro, content operators can make use of thesemacroefficiently fill and manage content, clear division of labor, and improve collaboration efficiency.
In summary, the Anqi CMS'smacroTags bring a functional programming experience to template development through their explicit parameter passing mechanism and strict scope management.It not only makes template code more tidy and reusable, but more importantly, it provides strong flexibility and controllability for the content operation of the website. It is an indispensable tool for building efficient and scalable CMS websites.
Common Questions (FAQ)
1.macroTags andincludeWhat are the differences in variable handling for tags?The main difference is the scope.includeTags will inherit all variable contexts from the parent template by default, unless you explicitly useonlyLimit it with keywords.macroTags are 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 I access the global configuration information of the site?macrosuch as the name of the site?SiteName?No,macrothe global template cannot be accessed directly internally