In AnQi CMS template development, we often encounter the need to reuse HTML code snippets or display logic.If you copy and paste every time, it not only increases the amount of code, reduces development efficiency, but also brings many inconveniences in later maintenance.To solve this problem, the AnqiCMS template engine provides a powerful macro function (Macro) that helps us achieve the reuse of display logic, making the template code more concise and efficient.
What is the template macro function?
The macro function can be understood as a custom function in the template.It allows us to encapsulate a commonly used HTML structure or display logic, define a set of parameters, and then call it multiple times anywhere in the template.This, when we need to display the same structured elements in different places, we only need to call the macro function and pass in different data, without repeating the same code.This greatly enhances the maintainability and development efficiency of the template.
How to define a macro function?
In AnQi CMS templates, defining macro functions is very intuitive, it uses syntax similar to the Python Django template engine. A macro function starts with{% macro 宏函数名(参数列表) %}and ends with{% endmacro %}End. The parameter list is used to receive the data required by the macro function at runtime, just like the parameters of a regular function.
Let's look at a practical example. Suppose we often need to display an article card on the page, including the article title, link, and summary.If writing this part of HTML every time seems very redundant.We can define aarticle_cardEncapsulate it with a macro function:
{# 定义一个名为 'article_card' 的宏函数,接收 'archive' 作为参数 #}
{% macro article_card(archive) %}
<div class="article-card">
<a href="{{ archive.Link }}" class="card-link">
<h3 class="card-title">{{ archive.Title }}</h3>
</a>
<p class="card-description">{{ archive.Description|truncatechars:100 }}</p>
<div class="card-meta">
<span>发布日期: {{ stampToDate(archive.CreatedTime, "2006-01-02") }}</span>
<span>浏览量: {{ archive.Views }}</span>
</div>
</div>
{% endmacro %}
In this example,article_cardThe macro function receives a namedarchiveThe parameter, this parameter is expected to be an article object, includingLink/Title/Description/CreatedTimeandViewsproperties. Inside the macro function, we use these properties to build the HTML structure of the article card.
How to use macro functions?
After defining a macro function, it can be used in the template just like a regular function. To call a macro function, double curly braces need to be used.{{ }}Wrap and pass the parameters defined by the macro function.
Continue with the above example, if we have a list of articlesarchivesNow you can be inforLoop and call it easily.article_cardMacro function to render each article card:
{# 假设 archives 是通过 archiveList 标签获取到的文章列表 #}
<div class="article-list">
{% for item in archives %}
{# 调用 article_card 宏函数,并将当前循环的 item 传入作为参数 #}
{{ article_card(item) }}
{% endfor %}
</div>
In this way, regardless of how many items are on the article list, we do not need to repeatedly write the HTML structure of the article card, we only need to define the macro function once and call it where needed, which significantly reduces the amount of code and makes maintenance easier.
Organize macro functions: Save them in separate files
As the complexity of the project increases, macro functions may become more numerous, and defining them all in a single main template file may make the file bulky. The Anqi CMS template engine supports defining macro functions in separate.htmlIn the file, import as needed, which helps maintain code modularity and neatness.
You can create a dedicated macro function file, for examplemacro_helpers.htmlDefine all general macro functions within it:
{# macro_helpers.html 文件内容 #}
{% macro article_card(archive) %}
<div class="article-card">
<a href="{{ archive.Link }}" class="card-link">
<h3 class="card-title">{{ archive.Title }}</h3>
</a>
<p class="card-description">{{ archive.Description|truncatechars:100 }}</p>
<div class="card-meta">
<span>发布日期: {{ stampToDate(archive.CreatedTime, "2006-01-02") }}</span>
<span>浏览量: {{ archive.Views }}</span>
</div>
</div>
{% endmacro %}
{% macro button_link(text, url, css_class) %}
<a href="{{ url }}" class="btn {{ css_class|default:"btn-default" }}">{{ text }}</a>
{% endmacro %}
Then, import them through the main template file where these macro functions are needed:{% import "文件路径" as 别名 %}Using the tag to import:
{# index.html 或其他主模板文件内容 #}
{# 从 "partial/macro_helpers.html" 导入宏函数,并赋予别名 "helpers" #}
{% import "partial/macro_helpers.html" as helpers %}
<div class="main-content">
<h2>最新文章</h2>
<div class="article-list">
{% for item in latest_archives %}
{{ helpers.article_card(item) }} {# 通过别名调用宏函数 #}
{% endfor %}
</div>
<div class="call-to-action">
{# 调用另一个导入的宏函数 #}
{{ helpers.button_link("查看更多文章", "/archives", "btn-primary") }}
</div>
</div>
Byas helpersAfter giving it an alias, we can use it through:helpers.宏函数名The form of calling macro functions, to avoid naming conflicts and improve code readability. You can also directly import macro function names, or import multiple macro functions and assign aliases to some of them.
The differences between macro functions and Include tags
In addition to macro functions, there is also another in the Anqi CMS templateincludeTags can also achieve code reuse. There are some important differences between them:
Scope (Variable Access)This is the main difference.
- Macro FunctionIt has an independent variable scope. It can only access variables explicitly passed to it as parameters and cannot directly access other variables in the parent template that called it.This makes the macro function more independent and predictable, making it an ideal choice for building pure, reusable components.
- Include TagIt will inherit all the variable context of the template it calls. This means that in the
includeIn the file, you can directly use any variables defined in the parent template.This is applicable for splitting the page layout (such as header, footer, sidebar) into small blocks, which usually need to access global or current page data.
Usage scenario:
- Macro function: Suitable for those logically independent, self-contained UI components, such as product cards, comment items, form input boxes, pagination buttons, etc., which need to receive specific data and display in a specific format.
- Include Tag: Suitable for larger parts of the page structure that depend on the entire page context, such as the common header, footer, navigation menu, or sidebar of a website, which may need to reference the website name, current user information, etc.
In short, when your code snippet needs to be highly independent and only rendered through passing parameters, choose a macro function; when your code snippet needs to access the entire data environment of the parent template, chooseinclude.
Summary
The macro function feature of AnQi CMS is a very practical technique in template development, which can effectively reduce redundant code and improve development efficiency and maintainability of the template.By reasonably defining, organizing, and using macro functions, we can build clear and easily expandable website templates, making content display more flexible and efficient.
Frequently Asked Questions (FAQ)
Can the macro function access the global variables of the current template?You cannot. Macro functions have their own scope and can only access variables explicitly passed to them as arguments.If you need to access global variables, you need to pass these global variables as arguments to the macro function.This is an important design principle that ensures the independence and predictability of macro functions.
Can I call another macro function within a macro function?Of course you can. You can call other macros that are already defined or imported within a macro function like you would call a regular macro function.This helps to build more complex, hierarchical reusable components.But it should be avoided to prevent infinite recursion.
If my macro function file is stored in
templateUnder the directorymacrosfolder, how should I import it?If your macro function file is located/template/default/partial/macros/my_macros.html(Assuming your template package name isdefault), then when importing in other templates, the path should be relative to the template root directory/template/default/to write. For example:{% import "partial/macros/my_macros.html" as my_tools %}. Make sure the path matches the actual file location