In website operation, maintaining content modularity and high reusability can not only significantly improve development efficiency, but also make the website more flexible in iterative updates.AnQiCMS (AnQiCMS) provides an intuitive and efficient solution to achieve this goal with its powerful template engine.This article will deeply explore how to make use of the template mechanism of Anqi CMS, cleverly引用external HTML fragments, such as headers and footers, to build a website that is easy to manage and structured.

The value of modular content: Why should we reference external HTML fragments?

Imagine a website with dozens or even hundreds of pages, if each page's header, footer, navigation bar, and other common parts need to be written separately, then any minor change will mean a huge amount of work.As the name implies, modular content is to extract the common components of a website (such as headers, footers, sidebars, navigation menus, etc.) and manage them as independent HTML files.When these modules need to be updated, we only need to modify one place, and all pages that refer to the module will be automatically synchronized, which greatly improves the maintenance efficiency, design consistency, and ease of team collaboration of the website.The template mechanism of Anqi CMS is specifically designed to meet such needs.

An enterprise CMS template mechanism overview: Building a flexible architecture with the power of Go language

The template engine of AnQi CMS is similar to Django, it adopts.htmlfiles as templates, and stores them uniformly in the root directory of the website./templateIn the folder. This design makes the template files easy to see and easy to manage. The core tool for implementing HTML fragment references in Anqi CMS is its built-in template tags, especiallyincludeandextendsThey are the foundation for building modular websites.

includeTag: Embeddable reusable HTML fragments

includeThe tag is used to embed an independent template file (or called a "code snippet") into another template file.This is the most direct way to implement modularization of common areas such as headers, footers, and sidebars.

For example, you usually save the header part of a website (including Logo, navigation bar, website title, etc.) as apartial/header.htmlfile, and save the footer information aspartial/footer.htmlFile. When you need to display these common parts on any page, just add the following code to the main template of the page:

{% include "partial/header.html" %}
<!-- 页面主体内容 -->
{% include "partial/footer.html" %}

Thus,header.htmlandfooter.htmlThe content will be 'pasted' at the current position at runtime.

includeThe tag also provides additional flexibility:

  • Optional introductionif_exists: If you are not sure if a fragment file exists, you can use{% include "some_optional_file.html" if_exists %}If the file does not exist, the system will not report an error, but simply ignore it, which is very practical in some dynamic or optional module scenarios.
  • Passing variableswithSometimes, you may need to pass some specific data to the imported snippet.includeTags allow you to usewithkeywords to pass variables. For example:{% include "partial/sidebar.html" with title="最新文章" count=5 %}.sidebar.htmlin, you can use it directly.{{title}}and{{count}}to retrieve these values.

ByincludeYou can easily divide the various general components of the website into independent, maintainable files, greatly enhancing the reusability and modification efficiency of the content.

extendsandblockLabel: Build page skeleton and content filling

Compared toincludeof "embedding",extendsTags provide a more powerful modular capability——template inheritance.It allows you to define a basic page layout (usually referred to as a "master" or "skeleton"), and then let other pages inherit this layout and only fill or modify specific areas within it.

A typicalbase.html(Master template) may include the following structure:

<!DOCTYPE html>
<html lang="{% system with name='Language' %}">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}{% tdk with name="Title" siteName=true %}{% endblock %}</title>
    <!-- 其他公共头部元素,如CSS、JS等 -->
</head>
<body>
    {% include "partial/header.html" %} {# 引入公共页头 #}

    <main class="container">
        {% block content %}
            <!-- 子页面将在这里填充主要内容 -->
        {% endblock %}
    </main>

    {% include "partial/footer.html" %} {# 引入公共页脚 #}
</body>
</html>

in thisbase.htmlIn:

  • {% block title %}and{% block content %}Defined areas that can be rewritten or filled by child templates.
  • NotblockThe part enclosed by tags (such as<!DOCTYPE html>/<html>, common CSS/JS,include "partial/header.html"/include "partial/footer.html"etc.) will be common to all pages inheriting this master page.

Now, if your article detail page needs to use this layout, you can create aarchive/detail.htmlfile, and write it like this:

{% extends 'base.html' %} {# 声明继承自 base.html,此标签必须是子模板的第一个标签 #}

{% block title %}
    <title>{% archiveDetail with name="Title" %} - {% system with name="SiteName" %}</title>
{% endblock %}

{% block content %}
    <article>
        <h1>{% archiveDetail with name="Title" %}</h1>
        <div>
            <!-- 文章的具体内容和信息 -->
            {% archiveDetail with name="Content" render=true|safe %}
        </div>
    </article>
{% endblock %}

Thus,archive/detail.htmlit inheritsbase.htmlthe overall structure and only overrides the page'stitleandcontentArea. When you visit the article detail page, it will automatically combinebase.htmlandarchive/detail.htmlthe content for rendering.

Template directory structure: clear management of modular files

It is crucial to follow a clear directory structure to better organize these modular HTML fragments.Anqi CMS provides two template organization modes: folder organization mode and flat file organization mode.The key is to put the common, reusable segments into a dedicated directory, regardless of the choice.

It is usually recommended to create a subdirectory namedpartial/in your template directory to store allincludepublic HTML fragments, such aspartial/header.html/partial/footer.html/partial/navigation.htmletc. And as the page skeleton ofbase.htmlIt can be placed directly in the root directory of the template.

Passing and rendering dynamic data

In modular templates, you can still fully utilize the various tags provided by Anqi CMS to obtain and render dynamic data. WhethersystemTags obtain website basic information,navListLabel to get navigation menu orarchiveListLabel to get the article list, they can be displayed in anyincludeorextendstemplate snippet. For example, yourpartial/header.htmlmay contain{% navList navs %}Generate navigation menu dynamically.

Summary

AnQi CMS, through its flexible template engine, especiallyincludeandextendsThese powerful tags provide comprehensive support for the modular display of website content.Reasonably utilizing these features can not only make your website development and maintenance more efficient, but also ensure that the website maintains a high degree of consistency in both visual and functional aspects.Abstracting common elements into reusable modules and constructing pages through inheritance and embedding is a key strategy for creating high-quality, easily scalable websites.


Frequently Asked Questions (FAQ)

1. Where should I place the CSS and JavaScript for the imported HTML snippet?

Generally, global CSS styles (such as reset.css, typography.css) and universal JavaScript libraries (such as jQuery) are placed inbase.htmlof<head>or<body>Bottom. You can choose the exclusive styles and scripts for specific modules (such as headers, footers, sidebars):

  • Inline to the fragment fileInpartial/header.htmlUse directly inside<style>and<script>Label. This is suitable for small code volumes and is highly coupled with the segment.
  • Introduce as a standalone file.Inbase.htmlIn it, use conditional judgment or direct links to introduce external CSS/JS files related to a specific module. For example, ifpartial/header.htmldepends onheader.css, you canbase.htmlof<head>introduce it in it.
  • pack and optimizeThe more advanced approach is to package and compress all CSS/JS files related to the modules, reduce HTTP requests, andbase.htmlintroduce the optimized files uniformly.

2.includeandextendsWhat is the difference, when should I use which?

  • includeSuitable forEmbeddedReusableIndependent code snippet. It is more like copy and paste, directly inserting the content of a file into the current position.For example, headers, footers, widgets, ad slots, etc., these fragments themselves do not define the complete page structure, but are just part of the page.
  • extendsSuitable forDefine the page skeleton and fill in the content. It is an inheritance relationship, where the child template inherits the overall layout of the parent template and then overrides the definitions in the parent template.blockarea.extendsIt is usually used to build the overall page layout, for example, all pages have the same header, footer, and sidebar, but the content area in the middle is different.

In short:

  • When you need to place in a pageInsertUse a complete, independently running UI componentinclude.
  • When you need to define a unified layout structure for the entire website or a certain type of pagea unified layout structureand allows subpages to customize some parts when usingextends.

3. How should I operate if I need to pass dynamic data to the imported fragment?

When you use{% include "partial/some_fragment.html" %}when introducedsome_fragment.htmlIt will inherit all the context variables of the current main template. This means that any variables defined in the main template can be used directly in the fragment

If you need to passadditionalor ofoverrideThe data of the existing master template variables can be usedwithKeyword:

{# 在主模板中 #}
{% set page_title = "首页" %}
{% include "partial/header.html" with current_nav_item="home", welcome_message="欢迎来到我们的网站!" %}

Inpartial/header.htmlIn it, you can access these variables in this way:

<h1>{{ welcome_message }}</h1>
<nav>
    <a href="/" {% if current_nav_item == "home" %}class="active"{% endif %}>首页</a>
    {# ... 其他导航项 #}
</nav>
<p>当前页面标题: {{ page_title }}</p> {# 仍然可以访问主模板的变量 #}

Please note thatwithThe variables passed have a higher priority than the same-named variables in the master template, but only in theincludeThe statement is valid within the scope. If you want to pass only specific variables without inheriting other variables from the main template, you canwithAdd afteronlykeywords.