安企CMS模板中,如何将公共的头部(header)和底部(footer)代码进行模块化重用?

在网站运营的日常工作中,效率和可维护性是决定项目成败的关键因素之一。尤其是在内容管理系统(CMS)中,如何高效地管理网站的公共元素,如头部导航、底部版权信息等,是每一个网站运营专家都会思考的问题。安企CMS(AnQiCMS)凭借其灵活的模板引擎和模块化设计理念,为我们提供了优雅的解决方案。

本文将深入探讨在AnQiCMS模板中,如何通过模块化策略,将公共的头部(header)和底部(footer)代码进行高效重用,从而提升网站的开发效率、降低维护成本并确保网站内容的一致性。

AnQiCMS模板引擎的核心优势

AnQiCMS的模板系统基于类似Django和Blade的语法,这使得熟悉这些模板语言的开发者能够快速上手。它的核心在于“一切皆可模块化”的设计思想。在AnQiCMS的模板约定中,我们能清晰地看到对公共代码和代码片段的重视。模板文件的根目录是/template,每个模板主题都在其下拥有独立的目录。对于公共的页头、页脚,系统推荐将它们放在bash.html这样的文件中供全局引用,而像侧边栏、面包屑等更小的代码片段,则建议存放在partial/目录中。这种结构化的组织方式,正是实现模板模块化重用的基石。

实现AnQiCMS模板模块化重用的主要工具是两个强大的标签:includeextends。它们各自扮演着不同的角色,协同工作,能够构建出既灵活又易于维护的网站结构。

include:代码片段的灵活插入

include标签的职责是将一个独立的、可复用的代码片段插入到当前模板的任何位置。你可以把它想象成乐高积木中的一块小砖,可以随意添加到任何大的结构中,而不会改变整个结构的形状。

在AnQiCMS中,如果你有一个导航菜单、一个广告位、或者一个简短的底部联系信息模块,这些模块可能在网站的多个页面中出现,但它们并不定义整个页面的布局骨架。这时候,include就派上用场了。

如何使用: 假设我们有一个公共的头部导航栏,可以创建一个名为 partial/header_nav.html 的文件,其中包含导航栏的所有HTML代码和AnQiCMS标签(例如,使用navList标签来动态生成导航链接)。

<!-- partial/header_nav.html -->
<header class="main-header">
    <div class="container">
        <a href="/" class="logo">
            <img src="{% system with name="SiteLogo" %}" alt="{% system with name="SiteName" %}">
        </a>
        <nav class="main-nav">
            <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-menu">
                                    {% for subItem in item.NavList %}
                                        <li><a href="{{ subItem.Link }}">{{ subItem.Title }}</a></li>
                                    {% endfor %}
                                </ul>
                            {% endif %}
                        </li>
                    {% endfor %}
                {% endnavList %}
            </ul>
        </nav>
    </div>
</header>

在任何需要这个导航栏的页面模板中,你只需简单地使用include标签:

<!-- index.html 或 detail.html -->
<body>
    {% include "partial/header_nav.html" %}
    <main>
        <!-- 页面主要内容 -->
    </main>
    <!-- 其他页面部分 -->
</body>

include标签还支持一些高级用法,例如,你可以通过with关键字向被包含的模板传递局部变量,或者使用if_exists来避免因文件不存在而引发的错误。

extends:构建页面骨架的利器

include不同,extends标签用于建立模板之间的继承关系,它定义了页面的整体结构或“骨架”。通常,我们会创建一个名为base.htmllayout.html的母版模板,其中包含所有页面共享的HTML结构、CSS和JavaScript引用,以及一些定义了可替换内容的block区域。

如何使用: 首先,我们创建一个基础布局文件,例如base.html

<!-- base.html -->
<!DOCTYPE html>
<html lang="{% system with name='Language' %}">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}{% tdk with name="Title" siteName=true %}{% endblock %}</title>
    <meta name="keywords" content="{% block keywords %}{% tdk with name="Keywords" %}{% endblock %}">
    <meta name="description" content="{% block description %}{% tdk with name="Description" %}{% endblock %}">
    <link rel="stylesheet" href="{% system with name="TemplateUrl" %}/css/main.css">
    {% block head_extra %}{% endblock %} {# 允许子模板插入额外的头部内容 #}
</head>
<body>
    {% block header %}
        {# 默认头部内容,可以在这里include一个公共头部文件 #}
        {% include "partial/header_nav.html" %}
    {% endblock %}

    <main id="content">
        {% block content %}
            {# 留给子模板填充主要内容 #}
            <p>这里是默认内容。</p>
        {% endblock %}
    </main>

    {% block footer %}
        <footer class="main-footer">
            <div class="container">
                <p>&copy; {% now "2006" %} {% system with name="SiteName" %}. All Rights Reserved.</p>
                <p>{% system with name="SiteCopyright"|safe %}</p>
                <nav class="footer-nav">
                    <ul>
                        {% navList navs with typeId=2 %} {# 假设typeId=2是底部导航 #}
                            {% for item in navs %}
                                <li><a href="{{ item.Link }}">{{ item.Title }}</a></li>
                            {% endfor %}
                        {% endnavList %}
                    </ul>
                </nav>
            </div>
        </footer>
    {% endblock %}

    <script src="{% system with name="TemplateUrl" %}/js/main.js"></script>
    {% block body_extra %}{% endblock %} {# 允许子模板插入额外的JS脚本 #}
</body>
</html>

接下来,任何其他的页面模板,比如首页index.html或文章详情页detail.html,都可以继承这个base.html

<!-- index.html -->
{% extends "base.html" %}

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

{% block content %}
    <h1>欢迎来到安企CMS网站</h1>
    <p>这里是首页的独有内容。</p>
    {# 首页可能包含更多独特的模块,可以继续include其他partial文件 #}
{% endblock %}

{% block head_extra %}
    <link rel="stylesheet" href="{% system with name="TemplateUrl" %}/css/index.css">
{% endblock %}

需要注意的是,{% extends %}标签必须是模板中的第一个标签,在其前面不能有任何其他内容,包括空格或换行。 否则,AnQiCMS模板引擎将无法正确解析继承关系。

模块化重用的**实践

结合includeextends,我们可以构建出高度模块化和可维护的AnQiCMS模板:

  1. **定义主布局(Master Layout)