如何设计一个基础模板并让其他页面继承它?

在安企CMS中构建网站,高效而灵活的模板设计是提升开发效率和保持网站一致性的关键。其中,设计一个基础模板并让其他页面继承它,是实现这一目标的核心策略。安企CMS采用了类似Django模板引擎的语法,这使得模板继承变得直观且功能强大。

奠定基石:创建你的基础模板

首先,我们来创建一个网站的基础骨架模板。在安企CMS中,所有的模板文件都存放在 /template 目录下,每个主题都有自己的独立文件夹。例如,如果你的主题名为 mytheme,那么模板路径就是 /template/mytheme/

在这个主题文件夹内,通常我们会创建一个名为 bash.html(或任何你喜欢的名称,约定俗成地,这是一个基础布局文件)的文件作为所有页面的公共基础。这个文件包含了网站的整体结构,比如 <head> 区块、顶部导航、页脚等,而将页面中会根据不同内容变化的区域定义为可供继承页面修改的“区块”。

bash.html 中,我们使用 {% block 你的区块名称 %}{% endblock %} 这样的标签来定义这些可变区域。例如:

<!DOCTYPE html>
<html lang="{% system with name='Language' %}">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- 页面TDK信息,这些标签会根据当前页面自动获取,如果当前页未设置,则获取后台配置的首页TDK -->
    <title>{% tdk with name="Title" siteName=true %}</title>
    <meta name="keywords" content="{% tdk with name="Keywords" %}">
    <meta name="description" content="{% tdk with name="Description" %}">
    {%- tdk canonical with name="CanonicalUrl" %}
    {%- if canonical %}
    <link rel="canonical" href="{{canonical}}" />
    {%- endif %}

    <!-- 引入网站的样式文件,TemplateUrl 会指向当前模板文件夹的静态资源路径 -->
    <link rel="stylesheet" href="{% system with name='TemplateUrl' %}/css/style.css">
    {% block head_extra %}{% endblock %} {# 预留给子页面添加额外的头部内容,如特定页面的CSS/JS #}
</head>
<body>
    <header class="site-header">
        <div class="container">
            <!-- 网站Logo和名称 -->
            <a href="{% system with name='BaseUrl' %}" class="logo">
                <img src="{% system with name='SiteLogo' %}" alt="{% system with name='SiteName' %}">
            </a>
            <!-- 导航菜单 -->
            <nav class="main-nav">
                {% navList navs %}
                <ul>
                    {% 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 subItem in item.NavList %}
                            <li class="{% if subItem.IsCurrent %}active{% endif %}">
                                <a href="{{ subItem.Link }}">{{ subItem.Title }}</a>
                            </li>
                            {% endfor %}
                        </ul>
                        {% endif %}
                    </li>
                    {% endfor %}
                </ul>
                {% endnavList %}
            </nav>
        </div>
    </header>

    <main class="site-main">
        <div class="container">
            {% block main_content %}
                <!-- 这里的默认内容,如果子页面不重写此block,则会显示 -->
                <p>这是基础模板的默认内容区域。</p>
            {% endblock %}
        </div>
    </main>

    <footer class="site-footer">
        <div class="container">
            <p>{% system with name="SiteCopyright" %}</p>
            <p><a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">{% system with name="SiteIcp" %}</a></p>
            <address>
                联系人:{% contact with name="UserName" %} | 电话:{% contact with name="Cellphone" %} | 邮箱:{% contact with name="Email" %}
            </address>
        </div>
    </footer>

    <!-- 引入网站的JavaScript文件 -->
    <script src="{% system with name='TemplateUrl' %}/js/main.js"></script>
    {% block body_extra %}{% endblock %} {# 预留给子页面添加额外的脚本 #}
</body>
</html>

可以看到,在这个 bash.html 模板中,我们使用了多个安企CMS的内置标签:

  • {% system with name="..." %}:获取网站全局配置,如语言、网站名称、Logo、备案号、基础URL、模板静态资源路径等。
  • {% tdk with name="..." %}:动态获取当前页面的SEO标题、关键词和描述,确保每个页面都有优化过的TDK信息。
  • {% navList navs %}:生成网站的主导航菜单。
  • {% contact with name="..." %}:获取网站的联系方式,方便在页脚等处展示。
  • {% block ... %}{% endblock %}:定义了 head_extramain_contentbody_extra 三个区块,这些是子页面可以覆盖或扩展的地方。

模块化构建:使用 include 标签

除了基础模板的继承,安企CMS还提供了 {% include "你的片段文件.html" %} 标签,用于引入一些小的、可复用的代码片段。这些片段通常不包含完整的HTML结构,而是像侧边栏、面包屑导航、广告位等,可以在多个页面中独立地插入。

例如,我们可以在 partial 目录下创建 sidebar.htmlbreadcrumb.html

/template/mytheme/partial/breadcrumb.html:

<div class="breadcrumb">
    {% breadcrumb crumbs with index="首页" title=true %}
    {% for item in crumbs %}
        {% if forloop.Counter < forloop.Length %}
        <a href="{{item.Link}}">{{item.Name}}</a> &gt;
        {% else %}
        <span>{{item.Name}}</span>
        {% endif %}
    {% endfor %}
    {% endbreadcrumb %}
</div>

然后在 bash.html 或其他子模板中,你可以在 main_content 区块内部使用 {% include "mytheme/partial/breadcrumb.html" %} 来引入它。include 标签可以帮助我们更好地组织模板文件,减少重复代码。

继承与重写:其他页面的实现

现在,当我们需要创建网站的首页、文章详情页、分类列表页等具体页面时,就不需要从头编写完整的HTML结构了。我们只需要让这些页面继承 bash.html,然后根据需要重写相应的 block 区块即可。

在任何一个子模板文件的**第一