As an experienced website operations expert, I am well aware of the importance of a powerful and flexible content management system (CMS) for corporate websites.AnQiCMS (AnQiCMS) leverages its high-performance architecture based on the Go language and Django template engine syntax, providing great convenience for content operations.In daily content management and website maintenance, we often use the built-in template tags to build dynamic pages.Today, I want to delve deeply into a topic about the practical but easily confusing aspect of Anqi CMS template development: macroCan the code snippet defined by the tag include other built-in template tags of AnQi CMS?
AnQi CMS template: In-depth analysismacroThe nesting capability and application strategy of tags
In the Anqi CMS template system, we will mainly encounter two types of structures: one is the double curly brace variable used for output data, such as{{变量}};Another is used for implementing logical control, loop traversal, and even data acquisition for more complex tasks, such as{% 标签 %}。AnQi CMS provides a rich set of built-in tags, ranging from obtaining system configurations(system), navigation lists(navList) to document details(archiveDetail), document lists(archiveListThese tags greatly simplify the process of building page content.
AndmacroA tag, as a member of the Anqi CMS template auxiliary tag, its core value lies in helping us define reusable code snippets or functions. It is like a function in a programming language, which can encapsulate a repeated HTML structure and the corresponding variable logic, and can be called in the place where it is needed.macroTo render, it avoids code redundancy, improves the maintainability and development efficiency of templates. For example, if we want to define a unified display style for each article list item,macroCan be put to use. The classic usage given in the document is to define it as receiving parameters, as shown in the following code snippet, which accepts aarchiveobject as a parameter and uses it internally{{archive.Id}}and{{archive.Title}}Show the article ID and title.
{% macro archive_detail(archive) %}
<li class="item">
<a href="/archive/{{archive.Id}}" class="link">
<h5 class="title">{{archive.Title}}</h5>
</a>
</li>
{% endmacro %}
Then,macroCan the tag inside contain other built-in template tags of AnQi CMS? This is a key issue that directly relates to how we design and organize templates.
Macro-defined code snippets should not generally contain built-in template tags used for independent data retrieval, such asarchiveList/system/categoryListetc.This is becausemacroThe design philosophy of the tag is to provide an encapsulated rendering logic, which expects to receive the required data from the outside, rather than initiating new data queries internally or obtaining global system configurations. According to the conventions of the Anqi CMS template tag,macroThe function “can only call variables passed as parameters” clearly defines its scope and data source.
This means that when you try to call in amacrodirectly.{% archiveList archives with limit="5" %}When trying to retrieve the latest list of articles, it usually fails. The macro's internal environment is relatively independent, and it does not have the ability to directly access the entire application context to perform such data queries.
However, this does not meanmacroThere should be no tags inside. In fact, it can completely contain conditional judgment tags ({% if ... %}), loop iteration tags ({% for ... %}), and even auxiliary tags likeincludeThe data for these label operations are all derived from the parameters of the macro itself, or from global variables available in the template inheritance chain, but do not require additional queries within the macro.
For example, if you want toarchive_detailin a macro, based onarchivea property of an object (such asarchive.HasImage), to decide whether to display an image, you can do this:
{% macro archive_detail(archive) %}
<li class="item">
<a href="/archive/{{archive.Id}}" class="link">
{% if archive.HasImage %}
<img src="{{archive.Thumb}}" alt="{{archive.Title}}" />
{% endif %}
<h5 class="title">{{archive.Title}}</h5>
</a>
</li>
{% endmacro %}
here,{% if archive.HasImage %}and{{archive.Thumb}}all depend on the inputarchiveThe parameter belongs to the parameter scope and is therefore completely legal.
**Practice and Suggestions
In order to make better use ofmacroLabel and maintain the clarity and efficiency of template code, we should follow the principle of 'Data and Display Separation':
Data acquisition is external, rendering logic is in
macro.IfmacroNeed to display a specific list of articles, system configuration, or category information, which should be accessed by callingmacrothrough the parent template.archiveList/system/categoryListtags. The data obtained is then passed as a parameter tomacro.- Incorrect example (it is not recommended to perform data retrieval directly within a macro)
{% macro latest_articles_macro() %} {% archiveList latest_articles with limit="5" %} {% for article in latest_articles %} <li>{{ article.Title }}</li> {% endfor %} {% endarchiveList %} {% endmacro %} - Correct approach (retrieve data externally and pass it to the macro for rendering)
{# template.html #} {% archiveList latest_articles with limit="5" %} {% import "macros.html" as my_macros %} {{ my_macros.render_article_list(latest_articles) }} {% endarchiveList %} {# macros.html #} {% macro render_article_list(articles) %} <ul> {% for article in articles %} <li>{{ article.Title }}</li> {% endfor %} </ul> {% endmacro %}
- Incorrect example (it is not recommended to perform data retrieval directly within a macro)
macroFocus on receiving parameters and structuring rendering.It should focus on how to display data consistently, rather than where to get the data. This makesmacroMore generic and reusable, can be used in different