When using AnQi CMS to manage website content, we often encounter scenarios where we need to display complex data or reuse similar layouts.If the display logic in the template is not organized effectively, it will soon be found that the template file becomes long and difficult to read, and it is also particularly difficult to maintain.Fortunately, the Anqi CMS template engine (which supports Django template engine syntax) provides powerful tools such as defining temporary variables and using macro functions, which can help us elegantly solve these problems and make the template code clear and efficient.
Why do you need more flexible template logic?
Imagine you are building a product display page, each product card needs to display product images, titles, prices, and brief descriptions.If each card repeats the HTML structure and data call logic of this content, then when the design needs to be fine-tuned, you will have to modify the code in dozens, even hundreds of places.The worse part is, if you need to perform intermediate calculations in a complex data loop or extract specific information from a nested data structure, directly stacking logic will make the template look like a tangled mess. Any small change may lead to unexpected errors.
At this point, introducing temporary variables and macro functions becomes particularly important. They can help us:
- Improve code readability:Break down complex data processing steps, representing intermediate results with meaningful variable names.
- Enhance maintainability:Centralize management of repeated display logic, one change, multiple effects.
- Improve development efficiency:Reduce the time spent on rewriting code, focusing on the implementation of business logic.
- Optimize performance:Avoid unnecessary repeated data queries or calculations (although this is more on the backend side, clear frontend logic helps with overall optimization).
Define temporary variables: make data accessible.
In Anqi CMS templates, we can use two main ways to define temporary variables:{% with %}Tags and{% set %}tags. They have different focuses and can be flexibly selected according to specific needs.
Use{% with %}Define a temporary variable
{% with %}主要用于在一段代码块内,临时声明一个或多个变量。其作用域仅限于这个with标签的内部,当代码执行到{% endwith %}When, these temporary variables will become invalid. This makes it very suitable for assigning the result of a complex expression to a readable variable, or for{% include %}Passing a template fragment with specific context data.
For example, we may need to perform a simple calculation on the prices in a product list and then display:
{% for product in productList %}
{% with originalPrice = product.Price, discountRate = 0.8 %}
{% set finalPrice = originalPrice * discountRate %}
<div class="product-card">
<h3>{{ product.Title }}</h3>
<p>原价: ¥{{ originalPrice }}</p>
<p>折扣价: ¥{{ finalPrice | floatformat:2 }}</p> {# 使用过滤器保留两位小数 #}
<a href="{{ product.Link }}">查看详情</a>
</div>
{% endwith %}
{% endfor %}
In this example,originalPriceanddiscountRateVariables are only in the currentproductThe loop inside is valid, making the calculation process clearer.
Use{% set %}Use tags to assign variables.
{% set %}The tag is more like the direct assignment operation in our usual programming language. It allows you to assign the result of an expression to a variable, which is in the current template file or the currentblockIt is valid until it is reassigned.{% set %}Used to store a single value, extract a specific attribute from a complex object, or perform some calculations that need to span multiple logical blocks.
Suppose we start from aarchiveDetailTag obtained multiple images but only want to display the first one as the cover image:
{% archiveDetail archiveImages with name="Images" %}
{% if archiveImages %}
{% set firstImage = archiveImages[0] %} {# 提取数组中的第一个元素 #}
<div class="article-cover">
<img src="{{ firstImage }}" alt="文章封面">
</div>
{% else %}
<div class="article-cover">
<img src="{% system with name='SiteLogo' %}" alt="默认封面">
</div>
{% endif %}
Here, firstImageThe variable stores the address of the first image in the article, which can be used elsewhere in the template without needing to extract it again.archiveImagesfrom it.
The art of encapsulating complex logic: The wonder of macro functions
When a template has large amounts of repeated HTML structure and logic, the macro function (Macro) is your savior.It allows you to define a reusable code block, like a custom template function, that accepts parameters and outputs content based on them.This greatly reduces code redundancy and makes the template more modular.
Defining and using macro functions
Using macro functions{% macro %}and{% endmacro %}Label to define. You can define the parameters accepted by the macro function after its name, which can be used like normal variables inside the macro function.
Assuming we have a generic product card layout, it needs to be displayed in multiple places on the website:
{# 定义在 partials/product_card.html 文件中 #}
{% macro render_product_card(product) %}
<div class="product-card-item">
<a href="{{ product.Link }}">
<img src="{{ product.Thumb }}" alt="{{ product.Title }}">
<h4>{{ product.Title | truncatechars:30 }}</h4>
<p class="price">¥{{ product.Price | floatformat:2 }}</p>
</a>
</div>
{% endmacro %}
Then, where we need to use this product card, we can through{% import %}Label import macro file and call macro function:
{# 在 index.html 或 list.html 中使用 #}
{% import "partials/product_card.html" as cards %} {# 导入宏文件并起别名 #}
<div class="latest-products">
<h2>最新产品</h2>
<div class="product-grid">
{% archiveList products with moduleId="2" type="list" limit="8" %}
{% for item in products %}
{{ cards.render_product_card(item) }} {# 调用宏函数,并传递产品数据 #}
{% empty %}
<p>暂无最新产品。</p>
{% endfor %}
{% endarchiveList %}
</div>
</div>
By macro function, we encapsulate the display logic of the product card, so that whenever a product card needs to be displayed on any page, it only requires a single line of code call, which is both concise and unified. If the design of the product card needs to be modified in the future (such as adding a "Buy Now" button), it only needs to be modifiedpartials/product_card.htmlThis file, all references to it will be automatically updated, greatly improving maintenance efficiency.
Combined with the actual scenario: making the template more powerful
Using temporary variables and macro functions together allows us to organize complex display logic more flexibly.For example, on a category list page, we may need to traverse multiple categories and display the latest several articles under each category.At the same time, the display method of each article can also be reused by a macro function.
{% import "partials/article_item.html" as article_macros %} {# 导入文章宏函数 #}
<div class="category-sections">
{% categoryList mainCategories with moduleId="1" parentId="0" limit="4" %}
{% for category in mainCategories %}
<div class="category-section">
<h2><a href="{{ category.Link }}">{{ category.Title }}</a></h2>
<div class="article-list">
{% archiveList articlesInCategory with categoryId=category.Id type="list" limit="5" %}
{% for article in articlesInCategory %}
{% with articleDate = stampToDate(article.CreatedTime, "2006-01-02") %} {# 临时变量格式化时间 #}
{{ article_macros.render_article_summary(article, articleDate) }} {# 调用宏函数,传递文章数据和格式化后的日期 #}
{% endwith %}
{% empty %}
<p>该分类暂无文章。</p>
{% endfor %}
{% endarchiveList %}
</div>
</div>
{% endfor %}
{% endcategoryList %}
</div>
In this more complex scenario,{% set %}and{% with %}Can be used to handle local data in loops, while{% macro %}Focuses on defining reusable UI components. When combined{% include %}and{% extends %}with these auxiliary tags