在安企CMS中,模板系统提供了强大而灵活的机制,让用户能够高效地定制网站的布局和内容展示。其中,“继承父模板并重写特定区块内容”是实现个性化设计和保持网站整体风格一致性的关键功能。

核心理念:告别重复,拥抱继承

想象一下,一个网站的头部、底部、侧边栏等元素,在几乎所有页面上都是固定不变的。如果没有模板继承机制,我们可能需要在每个页面模板中重复编写这些公共代码,这不仅增加了维护难度,也容易导致代码冗余和不一致。

安企CMS的模板引擎借鉴了Django的语法,它允许我们定义一个“骨架”模板(通常称为父模板或基础模板),其中包含了网站的通用结构和可重写的内容区域。子模板则基于这个骨架进行构建,它们无需重复编写通用部分,只需关注如何填充或修改父模板中定义的特定区域,从而实现定制化的内容展示。

基石:extendsblock 标签

在安企CMS模板中,实现这一机制的核心是两个标签:extendsblock

  1. extends 标签: 这个标签用于声明一个子模板所继承的父模板。它必须是子模板中的第一个非注释标签。例如,{% extends 'base.html' %} 意味着当前模板将继承 template 目录下的 base.html 作为其基础布局。通过它,子模板获得了父模板中定义的所有结构和内容。

  2. block 标签: block 标签在父模板中定义了一个可命名、可重写的内容区域。父模板会为这些区域提供默认内容(如果需要),但子模板可以选择性地覆盖这些内容。一个 block 标签总是成对出现,格式为 {% block 区域名称 %} ... {% endblock %}。例如,{% block title %}默认标题{% endblock %} 定义了一个名为 title 的区块,并提供了默认内容。

定制显示:子模板中的重写实践

当子模板通过 extends 继承了父模板后,它就可以通过定义与父模板中同名的 block 标签来重写该区块的内容。

例如,如果父模板 base.html 中有一个 {% block content %} 区块,子模板 index.html 就可以这样重写它:

{# index.html #}

{% extends 'base.html' %} {# 声明继承 base.html #}

{% block title %}
    <title>安企CMS首页 - 轻松定制你的网站</title> {# 重写父模板的 title 区块 #}
{% endblock %}

{% block content %}
    <div class="main-content">
        <h2>欢迎来到安企CMS!</h2>
        <p>这里是首页的定制内容,我们重写了父模板的 content 区块。</p>
        <p>你可以根据需要在此处添加文章列表、产品展示、轮播图等。</p>
    </div>
{% endblock %}

{# 子模板中未被 block 标签包裹的内容将不会被渲染 #}

在这个 index.html 子模板中:

  • {% extends 'base.html' %} 明确指定了它继承 base.html
  • {% block title %} 重写了父模板中 <title> 标签的内容,使其显示为“安企CMS首页 - 轻松定制你的网站”。
  • {% block content %} 则完全替换了父模板 content 区块中的默认内容,插入了首页特有的 HTML 结构和文本。

如果 index.html 没有定义 block header,那么 base.htmlheader 区块的默认内容将 그대로显示。这就是模板继承的魅力所在——按需定制,无需触碰通用部分。

实际操作:一步步定制你的安企CMS模板

让我们通过一个简单的示例来演示这个过程:

第一步:创建基础模板文件 (template/default/base.html)

假设你的模板目录名为 default。在 default 文件夹下创建一个 base.html 文件,内容如下:

{# template/default/base.html #}
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    {# 定义一个可重写的 title 区块 #}
    {% block title %}
        <title>我的安企CMS网站</title>
    {% endblock %}
    <link rel="stylesheet" href="{% system with name="TemplateUrl" %}/css/style.css">
    {# 定义一个可重写的 head 额外内容区块 #}
    {% block extra_head %}{% endblock %}
</head>
<body>
    <header>
        <nav>
            <a href="/">首页</a>
            <a href="/about.html">关于我们</a>
            <a href="/contact.html">联系我们</a>
        </nav>
        <hr>
    </header>

    <div class="container">
        {# 定义一个可重写的内容主体区块 #}
        {% block content %}
            <p>这里是网站的默认内容区域。</p>
            <p>子模板可以在这里填充或重写它们自己的内容。</p>
        {% endblock %}
    </div>

    <footer>
        <hr>
        <p>&copy; {% now "2006" %} {% system with name="SiteName" %}. All rights reserved.</p>
    </footer>
    <script src="{% system with name="TemplateUrl" %}/js/main.js"></script>
    {# 定义一个可重写的 body 额外内容区块 #}
    {% block extra_body %}{% endblock %}
</body>
</html>

这个 base.html 包含了 HTML 文档的基本结构、CSS/JS 引用,并定义了 titleextra_headcontentextra_body 四个可重写区域。

第二步:创建子模板文件 (template/default/index.html)

现在,我们来创建首页模板 index.html,让它继承 base.html 并重写其中的内容:

{# template/default/index.html #}
{% extends 'base.html' %}

{% block title %}
    <title>安企CMS官方网站 - 灵活高效的企业级内容管理系统</title> {# 重写 title 区块 #}
{% endblock %}

{% block extra_head %}
    <meta name="description" content="安企CMS是基于Go语言开发的企业级内容管理系统,提供高效、可定制、易扩展的解决方案。">
    <meta name="keywords" content="安企CMS, 内容管理, CMS, Go语言, 企业建站">
{% endblock %}

{% block content %}
    <div class="hero-section">
        <h1>欢迎使用安企CMS!</h1>
        <p>一个专为中小企业、自媒体和多站点管理设计的Go语言内容管理系统。</p>
        <a href="/docs/start.html" class="button">开始使用</a>
    </div>

    <section class="features">
        <h2>核心功能</h2>
        <ul>
            <li>多站点管理</li>
            <li>灵活的内容模型</li>
            <li>高级SEO工具</li>
            <li>防采集与水印管理</li>
        </ul>
    </section>

    {# 可以在这里调用安企CMS的标签来展示动态内容 #}
    <section class="latest-articles">
        <h2>最新文章</h2>
        <ul>
            {% archiveList archives with type="list" moduleId="1" limit="5" %}
                {% for item in archives %}
                    <li>
                        <a href="{{item.Link}}">{{item.Title}}</a>
                        <span>发布日期: {{stampToDate(item.CreatedTime, "2006-01-02")}}</span>
                    </li>
                {% empty %}
                    <li>暂无最新文章。</li>
                {% endfor %}
            {% endarchiveList %}
        </ul>
    </section>
{% endblock %}

{% block extra_body %}
    <script>
        // 只有首页才加载的JS逻辑
        console.log('首页特有的JS已加载。');
    </script>
{% endblock %}

当安企CMS渲染 index.html 时,它会首先加载 base.html 的结构,然后用 index.htmlblock title 的内容替换 base.html 中的 title 区块,用 block content 的内容替换 base.html 中的 content 区块,并插入 extra_headextra_body 的额外内容。

辅助标签与**实践

  • includeextends 的协作: extends 用于建立整个页面布局的层级关系,它决定了页面的“骨架”。而 include 标签则适用于复用更小的、独立的组件,比如一个侧边栏模块、一个评论表单或者一个产品卡片。它们互为补充,共同提高模板的复用性和可维护性。
  • extends 必须是子模板的第一个标签: 这是一个硬性规定。任何在 {% extends %} 之前出现的 HTML 代码、文本甚至空白字符(除了注释)都可能导致模板继承失败。
  • **善用 `