In the template development of AnQi CMS, we often encounter the need to reuse HTML code snippets or display logic.If you always copy and paste, it not only increases the amount of code, reduces development efficiency, but also brings many inconveniences during later maintenance.To solve this problem, the template engine of Anqi CMS provides a powerful macro function (Macro) feature that helps us achieve the reuse of display logic, making the template code more concise and efficient.
What is the template macro function?
Macros can be understood as 'custom functions' in templates.It allows us to encapsulate a frequently used HTML structure or display logic, define a set of parameters, and then call it multiple times anywhere in the template.This way, when we need to display the same structured elements in different positions, we just need to call the macro function and pass in different data, without repeating the same code.This greatly improves the maintainability and development efficiency of the template.
How to define a macro function?
In the template of AnQi CMS, defining macro functions is very intuitive, using syntax similar to Python Django template engine. A macro function starts with{% macro 宏函数名(参数列表) %}Start, with{% endmacro %}The end. The parameter list is used to receive data required by the macro function at runtime, just like the parameters of a normal function.
Let's look at a real example.The English translation of 'auto' is 'English'.If you write this part of HTML every time, it will be very redundant.article_cardTo encapsulate 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_cardA macro function receives a parameter namedarchiveThe parameter, this parameter is expected to be an article object, containingLink/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 as if it were a normal function. When calling a macro function, double curly braces must be used.{{ }}Wrap and pass parameters defined by the macro function.
Continuing with the previous example, if we have a list of articlesarchivesNow we can easily call inforthe loop.article_cardThe macro function to render each article card:
{# 假设 archives 是通过 archiveList 标签获取到的文章列表 #}
<div class="article-list">
{% for item in archives %}
{# 调用 article_card 宏函数,并将当前循环的 item 传入作为参数 #}
{{ article_card(item) }}
{% endfor %}
</div>
Through this way, no matter how many items the article list has, we do not need to repeat 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 and more, defining all of them in a single main template file can make the file bulky. The AnQi CMS template engine supports defining macro functions in independent.htmlIn the file, import as needed, which helps to maintain code modularity and neatness.
You can create a dedicated macro function file, for examplemacro_helpers.html,and define 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, in any main template file that needs to use these macro functions, through{% import "文件路径" as 别名 %}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>
Passas helpersAfter giving an alias, we can use it throughhelpers.宏函数名of the form to call macro functions, 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 another one in the AnQi CMS template.includeTags can also achieve code reuse. There are some important differences between them:
Scope (Variable Access)This is the main difference.
- Macro Function (Macro)English has its own variable scope.It can only access variables 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, which is the ideal choice for building pure and reusable components.
- Include TagIt will inherit all variable contexts of the parent template it calls. This means that in the called template,
includeIn the file, you can directly use any variables defined in the parent template.This is applicable for splitting page layout (such as header, footer, sidebar) into pieces, which usually require accessing global or current page data.
Use Cases:
- Macro function:Applicable to those logically independent and 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 general header, footer, navigation menu, or sidebar of a website. These parts may need to reference the website name, current user information, etc.
In short, when your code snippet needs to be highly independent and rendered only by passing parameters, choose macro functions; when your code snippet needs to access the entire data environment of the parent template, chooseincludeLabel.
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 the maintainability of templates.By reasonably defining, organizing, and using macro functions, we can build clear and extensible website templates, making content display more flexible and efficient.
Common Questions (FAQ)
Can the macro function access the global variables of the current template?Not allowed.The macro function has an independent scope, it can only access the variables that are explicitly passed to it as parameters.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, it 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 have already been defined or imported within a macro function, just like you would call a normal macro function.This helps to build more complex, hierarchical reusable components.But it is necessary to avoid circular calls to prevent infinite recursion.
If my macro function file is stored in
templatethe directory.macrosfolder, how should I import it?If your macro function file is located in/template/default/partial/macros/my_macros.html(Assuming your template package name is)default), then when importing in other templates, the path should be relative to the template root directory/template/default/. For example:{% import "partial/macros/my_macros.html" as my_tools %}. Make sure the path matches the actual file location