How to split a template into multiple reusable parts (such as header, footer)?

As an experienced operator of AnQiCMS, I know that content quality and website efficiency are the core factors to attract and retain users.In daily operations, we not only need to focus on the content itself, but also ensure the efficiency and maintainability of the website structure.The modular splitting of templates is the key technology to achieve this goal.

The AutoCMS provides a powerful and flexible template system that allows us to easily break down website templates into smaller, more manageable reusable parts, such as headers, footers, sidebars, etc.This method not only greatly improves development efficiency, ensures the consistency of the overall style of the website, but also simplifies the complexity of later maintenance and updates.

Anqi CMS template modularization basics

The template system of Anqi CMS is based on the syntax similar to Django template engine, with.htmlas the template file suffix, and stored uniformly in the/templatedirectory. Each template is throughconfig.jsonFile defines its properties. This design philosophy encourages us to abstract out commonly used page elements into independent 'code snippets' or 'skeletons', which can be referenced or inherited as needed.

The core idea is to avoid redundant work, and to make the common and frequently appearing elements in the website, such as the navigation bar, website footer copyright information, article sidebar, etc., independent files.Thus, once it is necessary to modify these common elements, we only need to change one file, and all the pages that reference it will be synchronized updated, greatly improving operational efficiency and the consistency of the website.

The strategy and practice of splitting reusable parts

To implement modular templates in the AnQi CMS, it mainly depends onextends/includeandmacrothese three tags, as well as following a specific directory structure.

Build website skeleton: Inheritance of header and footer (English)bash.htmlandextendsTag)

For the most stable and least changed common parts of the website, such as the entire page HTML structure, main CSS and JavaScript references, as well as the header and footer, we usually define them in a basic template, and Safe CMS recommends using it.bash.html文件作为这个“骨架”模板。

bash.html文件会包含页面的整体布局,并通过{% block 名称 %}{% endblock %}标签来定义可被子模板重写或填充的区域。例如,我们可以设置一个block titlefor the page title, ablock contentUsed for the main content, as well asblock scriptsJS code for specific pages.

{# /template/您的模板目录/bash.html #}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% system with name="SiteName" %}{% endblock %}</title>
    <link rel="stylesheet" href="{% system with name="TemplateUrl" %}/css/style.css">
    {% block head_scripts %}{% endblock %}
</head>
<body>
    <header>
        {# 引入页头公共部分 #}
        {% include "partial/header.html" %}
    </header>

    <main>
        {% block content %}
            {# 默认内容,可被子模板覆盖 #}
        {% endblock %}
    </main>

    <footer>
        {# 引入页脚公共部分 #}
        {% include "partial/footer.html" %}
    </footer>
    <script src="{% system with name="TemplateUrl" %}/js/main.js"></script>
    {% block body_scripts %}{% endblock %}
</body>
</html>

Then, all specific page templates in the website (such as the home pageindex/index.html, article detail page)archive/detail.htmletc.) can be accessed by{% extends 'bash.html' %}Labels inherit this basic skeleton. In the sub-template, we just need to rewrite the correspondingblockarea, fill in the unique content of this page. The areas that are not rewrittenblockwill be automatically沿用bash.htmlthe default content in it.

{# /template/您的模板目录/index/index.html #}
{% extends 'bash.html' %}

{% block title %}首页 - {% system with name="SiteName" %}{% endblock %}

{% block content %}
    <section class="hero-section">
        <h1>欢迎来到安企CMS</h1>
        <p>这是网站的首页内容区域。</p>
    </section>
    {# 首页特有的内容 #}
{% endblock %}

{% block body_scripts %}
    <script>
        console.log("这是首页特有的JS代码");
    </script>
{% endblock %}

细化组件:代码片段的引用 (English)partial/Directory andincludeTag)

对于网站中一些更小粒度、可能在多个 (English)block或不同子模板中重复使用的代码块,安企CMS建议将其存放在 (English)partial/The directory. For example, side navigation, breadcrumb navigation, ad slots, and rendering logic for article list items.

These code snippets can be referenced at any location.{% include "partial/文件名.html" %}Tags can be referenced at any needed location.includeThe power of tags lies in the fact that they can not only simply insert file content, but also pass variables to the included template throughwithparameters, even usingonlyLimit the scope of variables to ensure the independence of code segments.

For example, a general page headerpartial/header.htmlcan include the website logo and main navigation:

{# /template/您的模板目录/partial/header.html #}
<div class="site-header">
    <div class="logo">
        <a href="{% system with name="BaseUrl" %}">
            <img src="{% system with name="SiteLogo" %}" alt="{% system with name="SiteName" %}">
        </a>
    </div>
    <nav class="main-nav">
        {% include "partial/main_nav.html" %}
    </nav>
</div>

The main navigationpartial/main_nav.htmlcan be like this:

{# /template/您的模板目录/partial/main_nav.html #}
<ul>
    {% navList navs %}
        {%- for item in navs %}
            <li class="{% if item.IsCurrent %}active{% endif %}">
                <a href="{{ item.Link }}">{{item.Title}}</a>
                {%- if item.NavList %}
                    <ul class="sub-nav">
                        {%- for sub_item in item.NavList %}
                            <li class="{% if sub_item.IsCurrent %}active{% endif %}">
                                <a href="{{ sub_item.Link }}">{{sub_item.Title}}</a>
                            </li>
                        {% endfor %}
                    </ul>
                {% endif %}
            </li>
        {% endfor %}
    {% endnavList %}
</ul>

By this means, we can further encapsulate complex navigation logic. If aincludefile may not exist, you can useif_existsparameter to avoid errors in template rendering.

Advanced reuse: Macro function defines general rendering logic (macroTag)

When we need to reuse a piece of code with specific logic, and this code needs to accept parameters to dynamically generate content,macroLabels come into play.Macros functions are similar to functions in programming languages, which can define input parameters and render different HTML structures based on the parameters.They are very suitable for rendering individual items in article lists, product cards, comment boxes, and other UI components that appear repeatedly.

We can define macro functions in a separate.htmlfile, for examplepartial/macros.html:

{# /template/您的模板目录/partial/macros.html #}
{% macro render_article_card(article) %}
    <div class="article-card">
        <a href="{{ article.Link }}">
            {% if article.Thumb %}
                <img src="{{ article.Thumb }}" alt="{{ article.Title }}">
            {% endif %}
            <h3>{{ article.Title }}</h3>
            <p>{{ article.Description|truncatechars:100 }}</p>
            <small>{{ stampToDate(article.CreatedTime, "2006-01-02") }}</small>
        </a>
    </div>
{% endmacro %}

{% macro render_product_card(product) %}
    <div class="product-card">
        <a href="{{ product.Link }}">
            {% if product.Logo %}
                <img src="{{ product.Logo }}" alt="{{ product.Title }}">
            {% endif %}
            <h4>{{ product.Title }}</h4>
            <p class="price">¥ {{ product.Price }}</p>
        </a>
    </div>
{% endmacro %}

Then in other templates, you canimportinclude these macro functions with a tag and use them as if they were regular functions:

{# /template/您的模板目录/index/index.html #}
{% extends 'bash.html' %}
{% import "partial/macros.html" as my_macros %} {# 引入宏文件并设置别名 #}

{% block content %}
    <h1>最新文章</h1>
    <div class="article-list">
        {% archiveList archives with type="list" limit="4" %}
            {% for item in archives %}
                {{ my_macros.render_article_card(item) }} {# 调用宏函数渲染文章卡片 #}
            {% empty %}
                <p>暂无文章。</p>
            {% endfor %}
        {% endarchiveList %}
    </div>

    <h1>热门产品</h1>
    <div class="product-list">
        {% archiveList products with moduleId="2" type="list" limit="4" %}
            {% for item in products %}
                {{ my_macros.render_product_card(item) }} {# 调用宏函数渲染产品卡片 #}
            {% empty %}
                <p>暂无产品。</p>
            {% endfor %}
        {% endarchiveList %}
    </div>
{% endblock %}

Actual operation and precautions

There are several points to pay special attention to when splitting the template:

  • Consistency in syntax:SafeCMS uses a template syntax similar to Django, variables are enclosed in double curly braces{{变量}},control structures (such as conditional judgments, loops) use single curly braces and percent signs{% 标签 %}.
  • Static resource managementThe styles, JS scripts, images, and other static resources referenced in the template should be stored uniformly in/public/static/In the directory, and through{% system with name="TemplateUrl" %}Label dynamically retrieves the static resource path of the template, ensuring correct reference under multi-template environments.
  • Unified CodingAll template files must use UTF-8 encoding to avoid problems with Chinese characters.
  • Sorted from largest to smallest:Suggestion from overall layout (extends) Starting, gradually refining to page blocks (include) Finally, to the parameterizable independent UI components (macro).
  • Variable passing and scopeUnderstandingincludeandmacroThe difference in variable passing and scope between tags, choose to use them reasonably.includeWill inherit all variables of the current template,macroand will only use the parameters explicitly passed in.

By effectively splitting templates, website operators of Anqi CMS can build websites with clear structure, easy maintenance, and efficient response to changes.This not only improves the development and management experience of the website front-end, but also indirectly provides a solid technical foundation for the quick publication and optimization of content.

Common Questions and Answers (FAQ)

1. Why is it so important to modularize the template in AnQiCMS?

The template modular splitting is crucial for enhancing the efficiency of website operation.It ensures high consistency in both visual and functional aspects of the website, reducing repetitive code, thereby significantly lowering the development and maintenance costs of templates.When it is necessary to modify a certain public element, it is only required to operate in one file, and all pages that reference the element will be updated automatically, which avoids the cumbersome manual modification and effectively reduces the possibility of errors.

2. How should one decide which parts should be used when splitting templates?include, and which should be used?extends, again, what are suitable to usemacro?

Usually,extendsused to define the basic structure and common layout of the entire page (such as)bash.html),which defines what can be overridden by sub-templatesblockarea.include更适合引入页面中较小的、独立的、可以在多个地方重复使用的静态或半静态代码片段(如页头、页脚、侧边栏导航)。而macro则适用于