What are the core differences between `macro` tags and `include` tags in terms of variable scope and code reuse?

As an experienced website operations expert, I have a deep understanding of the powerful functions and content operation strategies of AnQiCMS (AnQi CMS).AnQi CMS, with its efficient architecture based on the Go language, flexible content model, and friendly SEO support, has become the preferred tool for many small and medium-sized enterprises and content operation teams.In template development, how to efficiently and safely reuse code is the key to improving operational efficiency, andmacrowith the tag andincludeLabels are the two great tools to achieve this goal.

However, many developers who are new to the Anqi CMS template often feel confused about the usage scenarios of these two tags, especially the core differences in variable scope and code reuse methods.Today, let's delve into the unique features of these 'twin brothers'.

includeLabels: 'Legos' for template assembly.

Imagine that your website has many pages, and they all share some common elements, such as the header (Header), footer (Footer), or sidebar (Sidebar).These parts of the code are often fixed or only slightly different in a few places. At this time,includeLabels are like pre-fabricated Lego blocks, allowing you to directly insert these independent functional modules into any required template file.

Its core idea is 'Direct Embedding': when you use{% include "partial/header.html" %}the system will convertheader.htmlThis file's content is loaded unchanged into the corresponding position of the current template. This method is concise and efficient, especially suitable for those static code blocks that are relatively stable and not subject to frequent changes.

In terms of variable scope,includeThe tag has a very important feature:By default, it will inherit all available variables in the current templateThis means that any data you define in the main templateincludecan be directly accessed in the incoming sub-template. For example, if your main template defines{{ siteName }}this website name variable, thenheader.htmlEven if it is not explicitly received, it can be used directly{{ siteName }}to display.

Of course, if you want to pass an additional, module-specific variable toincludethe template, you can usewithKeywords. For example, if you want to display a special title in the header of a page you are introducing, you can write it like this:{% include "partial/header.html" with pageTitle="安企CMS官网" %}. At this point,header.htmlIt can be accessed through{{ pageTitle }}to get this value.

Further, if you worry about beingincludethe template accidentally accessing variables in the main template that you don't want it to know, or to maintain the purity of the code, you can also addonlyKeyword:{% include "partial/header.html" with pageTitle="安企CMS官网" only %}. This way,header.htmlcan only access throughwithExplicitly passed inpageTitleVariables, any other variables in the main template will not be visible. It's like setting up an independent power supply for the Lego bricks, only to light up its own bulbs.

macroLabel: Flexible Customized "Function Factory"

withincludeDirectly embedded is different,macroThe label is more like a 'template function' or 'code factory'.It allows you to define a parameterized, reusable code snippet that can then be used to generate different HTML content as needed.This is especially powerful when it is necessary to display different data in the same structure, such as each product card in a product list, each article summary in an article list.

macroThe key to the tag is itsStrict variable scope isolation. OnemacroMacros defined internally,Can only access variables explicitly passed through parameters. It does not automatically inherit any variables from the parent template, even if you define them in the main templatesiteName,macroIt cannot be used internally directly. This sandbox mechanism ismacroThe most distinctive feature of the tag, and the foundation for its high modularity and avoidance of variable conflicts.

For example, suppose you need to display an article list on multiple pages, with the same layout and style for each list item, but different content displayed for each article. In this case, you can define amacroRender a single article item:

{# 定义在单独的文件如:archive.helper中 #}
{% macro article_card(item) %}
<li class="article-item">
    <a href="{{ item.Link }}">
        <img src="{{ item.Thumb }}" alt="{{ item.Title }}" class="article-thumb">
        <h5 class="article-title">{{ item.Title }}</h5>
        <p class="article-description">{{ item.Description|truncatechars:100 }}</p>
        <span class="article-date">{{ stampToDate(item.CreatedTime, "2006-01-02") }}</span>
    </a>
</li>
{% endmacro %}

Then in your main template, you need to useimportto include this macro, and then use it like a function:

{# 在主模板中引入宏文件 #}
{% import "archive.helper" article_card %}

{# 调用 archiveList 标签获取文章数据 #}
{% archiveList archives with type="list" limit="6" %}
    <ul class="article-list">
        {% for article in archives %}
            {# 将每篇文章数据 item 传入 macro 进行渲染 #}
            {{ article_card(article) }}
        {% endfor %}
    </ul>
{% endarchiveList %}

here,article_cardThe macro only knows it throughitemThe data received as a parameter, it is not necessary to care about itarchivesHow variables are obtained, also not affected by any other variables in the main template. This clear division of responsibilities makes the template code easier to understand, maintain, and collaborate with the team.

The core difference: variable scope and code reuse philosophy

In summary,macroandincludeThe fundamental difference lies inVariable scopeandThe philosophy of code reuse.

  1. Variable scope:

    • include:By default, it shares all variables of the parent template. It can be accessed throughwithPass by value, throughonlyLimit to using the passed variables. Its scope is wider, more 'open'.
    • macro:Strict isolation. Can only access variables explicitly passed as parameters. Its scope is narrower and more "enclosed", eliminating the possibility of variable name conflicts.
  2. Code reuse method:

    • include:Focuses on "structural reuse". It embeds a complete or partial template file into another template, suitable for the overall layout of websites, fixed blocks (such as navigation, advertising slots), and so on.can be considered as modular static content.
    • macro:Focuses on 'functional reuse'. It defines a parameterizable logic snippet, like a function, that receives data and generates HTML, suitable for components that need to render the same structure repeatedly but with different data (such as list items, cards, form fields).Can be considered as a component of dynamic content.

In simple terms, when you need to insert an "independent HTML snippet" on a page, chooseincludeWhen you need to 'repeat generating the same HTML structure with different data' on the page, choosemacro.

Why are these differences important?

Understand and properly applymacroandincludeThe difference is crucial for content operators and template developers of AnQi CMS:

  • Improve code quality and maintainability: macroThe strict scope avoids variable conflicts, reduces the risk of introducing unexpected bugs, and has obvious advantages in large and complex templates or when working in teams.
  • Optimize the structure and readability of the template:A logically clear template is easier to understand and reduces the cost of later maintenance. UsemacroEncapsulate repeated rendering logic to make the main template focus more on data flow and component composition.
  • Enhance the flexibility and extensibility of the template: macroCan handle data in a parameterized manner, allowing the same macro to be applied to different data sources, greatly enhancing the reusability and adaptability of templates.When you need to adjust the style or logic of a component, you only need to modify the macro definition, and all the places that call the macro will update automatically.
  • Improve development efficiency:Avoids rewriting a large amount of similar code, generating complex content through simple parameter passing, greatly speeding up template development speed.

The reason why AnQi CMS provides two different template reuse mechanisms is to meet various development needs and scenarios.As operation experts, we know that in efficient content management, the neatness, maintainability, and flexibility of code are equally important. Make good use ofmacroandincludeCan it give wings to your Anqí CMS website template development, easily building high-quality websites that are professional and easy to manage.


Frequently Asked Questions (FAQ)

Q1: Can I define it inside theincludefile definition.macroThen use this in the parent template that includes this filemacro?

A1: No.macroThe definition must be passed throughimportThe tag must be explicitly introduced to use. If you define it in a file that isincludedefined inmacromacro only in theincludeVisible within the file (if it uses itself), or needs to be referenced by other templatesimportmerelyincludeA file does not make its internally definedmacroautomatically available in the parent template.

Q2: If myincludefile needs a specific variable, but I don't want it to inherit all the variables from the parent template, what should I do?

A2: That is exactlywithandonlyThe place where the keyword is used. You can write it like this{% include "partial/my_specific_component.html" with data=my_data only %}Thus,my_specific_component.htmlThe template can only access todataThis variable, will not inherit other properties from the parent template