How to use the `macro` tag in AnQiCMS to define reusable content display components and improve template efficiency?

In AnQiCMS template development, 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 repeated code not only reduces development efficiency, but also makes subsequent maintenance and modification cumbersome. 幸运的是,AnQiCMS providedmacroTags, it allows us to define reusable content display components, managing template code as if writing small functions, thereby greatly enhancing template efficiency and maintainability.

What ismacroTag?

macroTags can be understood as 'micro-functions' or 'components' in templates.It allows you to define a template code snippet with parameters.When you need to use this code multiple times, you just need to pass different parameters, like calling a function,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 usemacrofundamentals

definitionmacroThe syntax is very intuitive:

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

Once defined,macroYou 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 scope is independent, it can only access variables passed in through parameters. This meansmacroMore pure, it will not unexpectedly modify or depend on other variables in the external environment, thereby enhancing its reusability and stability.

Actual case: Build a reusable article card component

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

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

    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 in the main templatemacroNow, whether it isindex.html/article/list.htmlOrsearch/index.htmlThrough, we can all passimportIntroduce and use this tagarticle_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 %}
    

In this way, we define the structure and style of the article card only once, but can use it repeatedly in many 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_cardMacros, all references to it will be automatically updated, which greatly saves the cost of modification.

Further progress: organizationmacroFile

In a large website project, it may be defined many.macro. To keep the template file neat and easy to manage, it is usually a good practice to place different functionsmacroin different files. For example:

  • _article_macros.html: Contains 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 utility macros.

When needed, you can introduce one or more macros based on specific requirements, even throughasThe keyword is used to set aliases for the introduced macros 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

usemacroTag-based template development can bring many advantages to our website:

  • improve development efficiency: Write once, use anywhere, avoid repetitive work, and accelerate development progress.
  • Maintain code consistencyAll repeated components use the samemacroGenerated, ensuring the overall style consistency and interface standardization of the website.
  • Simplify template maintenanceWhen the website design needs to be adjusted, it only needs to be modifiedmacroDefine the file, all pages referencing the component will be automatically updated, greatly reducing maintenance costs
  • Improve the readability of the template: Encapsulate complex HTML structures inmacro, making the main template code more concise, clear, easy to understand and review.
  • Promote teamwork: Team members can focus on their respectivemacroComponent development, then throughimportTags integrated in the main template, improving collaboration efficiency.

On the whole, AnQiCMS'smacroTags are a powerful tool in template development, which helps us achieve 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 and chaotic template code, thus having more energy to focus on content creation and website operation itself.


Frequently Asked Questions (FAQ)

1.macroandincludeWhat are the differences 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 internal scope, accessible only through the data passed in as parameters. This makesmacroVery suitable for creating configurable, logically structured UI components (such as article cards, buttons), which can generate different content each time they are called according to the parameters passed in.
  • include(including)It is more like a simple 'copy and paste'. It will directly insert the content of the specified file at the current position.includeThe default inherits all context variables of the current template. It is often used to introduce fixed parts in the page (such as headers, footers, sidebars), which usually do not change much or need to access all the data of the current page.

In simple terms,macroIt is a good choice to create 'smart components', andincludeSuitable for inserting a "static segment".

2.macroWhat types of data can the parameter pass?

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

  • string(String): such as{{ macro_name("这是一个字符串") }}.
  • Number(Integer/Float):such as{{ macro_name(123) }}or{{ macro_name(3.14) }}.
  • Boolean(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) }}.
  • array/slice(Array/Slice):Can pass a list of data.

**3. Can I use other AnQiCMS tags and filtersmacrowithin it?