How to define reusable content display components using AnQiCMS's `macro` tag to improve template efficiency?

In the template development of AnQiCMS, we often encounter situations where we need to repeatedly write the same or similar code blocks, such as article cards on the website, product display blocks, or buttons with specific styles.This repetitive code not only reduces the development efficiency, but also makes subsequent maintenance and modification cumbersome.macroThe label that allows us to define reusable content display components, managing template code like writing small functions, thereby greatly enhancing template efficiency and maintainability.

What ismacroTags?

macroThe label can be understood as a "micro function" or "component" in the template.It allows you to define a template code snippet with parameters.macroIt will generate the corresponding HTML content based on these parameters.This is like defining a function in programming to perform a specific task, and calling the function directly each time the task is needed without rewriting all the logic.

Define and usemacroEnglish's basis

definedmacroThe syntax is very intuitive:

{% macro 宏名称(参数1, 参数2, ...) %}
    {# 这里是宏要输出的HTML代码 #}
    {# 可以使用传入的参数来动态生成内容 #}
{% endmacro %}

Once definedmacro, you can use it anywhere in the template, just like calling a regular variable, and passing the corresponding parameter value:

{{ 宏名称(值1, 值2, ...) }}

It is worth noting that,macroThe internal scope is independent, it can only access variables passed in as parameters. This meansmacroMore pure, it will not accidentally modify or depend on other variables in the external environment, thereby enhancing its reusability and stability.

Actual case: Construct a reusable article card component

Our website homepage, category list page, and search results page all need to display article summaries. Each summary includes a title, thumbnail, description, and link. If there is nomacroWe may need to repeat the similar article card HTML structure on each page.macroWe can operate like this:

  1. Create macro filesTo better organize the code, we can put allmacroDefine it separately in a file, for example, in/template/你的模板目录/partial/Create a folder and name it_macros.html[en] of the file.

    In_macros.htmlDefine an article card inmacro:

    {# partial/_macros.html #}
    {% macro article_card(article) %}
        <div class="article-card">
            {% if article.Thumb %}
                <a href="{{ article.Link }}" class="card-thumb">
                    <img src="{{ article.Thumb }}" alt="{{ article.Title }}">
                </a>
            {% endif %}
            <div class="card-content">
                <h3 class="card-title">
                    <a href="{{ article.Link }}">{{ article.Title }}</a>
                </h3>
                <p class="card-description">{{ article.Description|truncatechars:100 }}</p>
                <div class="card-meta">
                    <span>发布于:{{ stampToDate(article.CreatedTime, "2006-01-02") }}</span>
                    <span>阅读:{{ article.Views }}</span>
                </div>
            </div>
        </div>
    {% endmacro %}
    
    
    {# 如果还有其他类似的宏,可以继续在这里定义,比如 product_card 等 #}
    
  2. Include and use it in the main templatemacroNow, whether it isindex.html/article/list.htmlOrsearch/index.htmlEnglish, we can all pass throughimporttag introduction and use thisarticle_cardmacro.

    For example, inindex.htmlIn:

    {# index.html #}
    {% extends 'base.html' %}
    {% import "partial/_macros.html" article_card %} {# 引入 article_card 宏 #}
    
    
    {% block content %}
        <div class="articles-section">
            <h2>最新文章</h2>
            <div class="article-list-grid">
                {% archiveList latestArticles with type="list" limit="6" order="id desc" %}
                    {% for article in latestArticles %}
                        {{ article_card(article) }} {# 直接调用宏,传递文章数据 #}
                    {% empty %}
                        <p>暂无最新文章。</p>
                    {% endfor %}
                {% endarchiveList %}
            </div>
        </div>
    
    
        {# 假设另一个地方也需要文章卡片 #}
        <div class="featured-articles">
            <h2>推荐阅读</h2>
            <div class="article-list-flex">
                {% archiveList featuredArticles with type="list" flag="c" limit="3" %}
                    {% for article in featuredArticles %}
                        {{ article_card(article) }} {# 再次调用宏 #}
                    {% empty %}
                        <p>暂无推荐文章。</p>
                    {% endfor %}
                {% endarchiveList %}
            </div>
        </div>
    {% endblock %}
    

Through this method, we define the structure and style of the article card only once, but can reuse it in multiple places. If we need to modify the layout of the article card or add new display elements in the future, we only need to modify_macros.htmlofarticle_card宏,all references to it will be automatically updated, which greatly saves the cost of modification.

Further: OrganizationmacroFile

In a large-scale website project, many definitions may be definedmacroTo maintain the cleanliness of the template file and facilitate management, it is usually necessary to place different functionsmacroin different files. For example:

  • _article_macros.html: store macros related to article display.
  • _product_macros.html:Stores macros related to product display.
  • _form_macros.html:Stores macros related to form elements (such as input boxes, selection boxes).
  • _utility_macros.html:Stores some general-purpose small tool macros.

When needed, one or more macros can be introduced according to specific requirements, even throughasAn alias can be set for the macro introduced by the keyword to avoid naming conflicts or to make the call more contextual:

{# 引入多个宏,并为其中一个设置别名 #}
{% import "partial/_macros.html" article_card, product_card as p_card %}

{{ article_card(some_article) }}
{{ p_card(some_product) }}

macroBenefits brought

adoptsmacroDeveloping templates with tags can bring many advantages to our website:

  • Improve development efficiency: Write once, use anywhere, avoid repetitive work, and accelerate development progress.
  • Maintain code consistency: All repeated components use the samemacroGenerate, ensuring the overall style consistency and interface standardization of the website.
  • Simplify template maintenanceWhen the website design needs adjustment, only the modification is requiredmacroDefine the file, all pages that refer to this component will be automatically updated, greatly reducing maintenance costs.
  • Enhance the readability of the template:Encapsulate complex HTML structures inmacro,making the main template code more concise, clear, easy to understand and review.
  • Promote team collaboration:Team members can focus on their respectivemacroComponent development, then throughimportIntegrated tags in the main template to improve collaboration efficiency.

On the whole, AnQiCMS'smacroTags are a powerful tool in template development, helping us achieve the componentization and modularization of templates in a simple and effective way, making website construction more efficient and organized. By making reasonable use ofmacroWe can say goodbye to repetitive, chaotic template code, thus having more energy to focus on content creation and website operation itself.


Common Questions (FAQ)

1.macroandincludeWhat is the difference between tags?

macroandincludeAll are used for code reuse in templates, but they have different focuses and behaviors.

  • macro(Macro):It is more like a 'function'. It accepts parameters and has an independent inner scope, which can only access data passed in through parameters. This makesmacroIt is very suitable for creating configurable, specific logic UI components (such as article cards, buttons), which can generate different content each time they are called with input parameters.
  • include(include)It is more like a simple 'copy and paste'. It directly inserts the content of the specified file at the current position.includeIt will inherit all the context variables of the current template by default.It is often used to introduce fixed parts of the page (such as headers, footers, sidebars), which usually do not change much or need to access all the data on the current page.

In simple terms,macrois a good choice for creating 'smart components', andincludeSuitable for inserting "static segments".

2.macroWhat types of data can the parameters pass?

macroThe parameter is very flexible, can pass almost all data types supported by the AnQiCMS template environment, including but not limited to:

  • String(String): as{{ macro_name("这是一个字符串") }}.
  • Number(Integer/Float):such as{{ macro_name(123) }}or{{ macro_name(3.14) }}.
  • Boolean value(Boolean):such as{{ macro_name(true) }}or{{ macro_name(false) }}.
  • object/structure(Object/Struct): This is the most common way, you can directly pass a complete article object or category object, such as{{ article_card(item) }}.
  • an array/slice(Array/Slice):可以传递一个列表数据。

**3. 我可以在macro内部使用其他的 AnQiCMS 标签和过滤器吗