在使用 AnQiCMS 搭建网站时,我们常常会遇到这样的情况:网站的每个页面都有共同的头部导航、底部信息,或者某个模块(比如侧边栏、文章推荐列表)需要在多个地方展示,但内容或样式可能略有不同。如果每次都复制粘贴这些代码,不仅效率低下,而且一旦需要修改,就得在所有相关页面逐一调整,非常容易出错且难以维护。

AnQiCMS 充分考虑到了这种需求,它内置了强大的模板继承和引用功能,让我们能够像搭建积木一样,高效、灵活地构建网站,确保代码的可重用性和网站的易维护性。掌握这些功能,你就能轻松驾驭模板,让网站的开发和运营变得更加顺畅。

一、为什么需要可重用的显示模块?

在网站内容运营和开发过程中,可重用模块的重要性不言而喻:

  1. 提升效率:无需重复编写相同的 HTML 结构或功能代码,大大缩短了开发时间。
  2. 保持一致性:通过集中管理公共模块,可以确保网站各部分风格和功能的统一,提升用户体验。
  3. 简化维护:当网站设计或功能需要调整时,只需修改一处核心模块,所有引用该模块的地方都会同步更新,避免了繁琐的手动修改,降低了出错的风险。
  4. 易于扩展:可以轻松地在现有结构中插入新的功能模块或替换旧的模块,使得网站能够快速适应业务变化。

AnQiCMS 采用类似 Django 模板引擎的语法,这使得模板的继承和引用非常直观和强大。变量通常使用 {{变量}} 的双花括号形式,而逻辑控制标签,如条件判断和循环,则使用 {% 标签 %} 的单花括号加百分号形式,且大多数逻辑标签都需要对应的结束标签,如 {% if ... %} ... {% endif %}

二、模板继承:构建网站的“骨架”

模板继承是构建网站整体布局的核心功能,它允许你定义一个基础的、包含网站通用结构(如头部、底部、侧边栏)的“母版”模板,然后让其他页面模板来继承这个母版。

  1. 核心理念: 模板继承就像为你的网站制作一个“万能底稿”。你可以在这个底稿上画出所有页面都共有的部分,并预留一些“空白区域”(即 block 标签),让继承它的子模板来填充这些空白区域,或者选择使用底稿中预设的默认内容。这样,所有子页面都会拥有相同的骨架,但具体内容可以各不相同。

  2. 如何使用 extendsblock 标签

    • 定义母版 (base.html): 通常,我们会在模板目录下创建一个 base.html 文件,作为网站的母版。在这个文件中,你可以定义整个页面的 HTML 结构、引入 CSS 和 JavaScript 文件,并使用 {% block 块名称 %}{% endblock %} 标签来定义可被子模板覆盖的区域。

      <!DOCTYPE html>
      <html lang="zh-CN">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          {# 头部标题,可被子模板覆盖 #}
          {% block title %}
              <title>我的网站 - AnQiCMS</title>
          {% endblock %}
          <link rel="stylesheet" href="{% system with name="TemplateUrl" %}/css/style.css">
          {% block head_extra %}{% endblock %} {# 预留给子模板添加额外的head内容 #}
      </head>
      <body>
          <header>
              {% include "partial/header.html" %} {# 头部导航,通常作为一个独立模块引用 #}
          </header>
      
      
          <div class="main-content">
              <aside class="sidebar">
                  {% block sidebar %}
                      {# 默认侧边栏内容,子模板可覆盖 #}
                      <p>这里是默认的侧边栏内容。</p>
                      {% include "partial/latest_articles.html" %} {# 推荐文章模块 #}
                  {% endblock %}
              </aside>
      
      
              <main class="content-area">
                  {% block content %}
                      {# 页面主要内容区域,子模板必须填充 #}
                      <p>欢迎来到我的网站!</p>
                  {% endblock %}
              </main>
          </div>
      
      
          <footer>
              {% include "partial/footer.html" %} {# 底部信息,通常作为一个独立模块引用 #}
          </footer>
          {% block body_extra %}{% endblock %} {# 预留给子模板添加额外的body内容,例如JS脚本 #}
      </body>
      </html>
      
    • 继承母版 (index.html 或其他页面): 在子模板中,你需要做的第一件事就是使用 {% extends '母版文件路径' %} 标签来声明它继承哪个母版。请注意,extends 标签必须是子模板中的第一个标签。 接着,你可以使用同名的 {% block 块名称 %} 标签来填充或覆盖母版中预留的区域。

      {% extends 'base.html' %} {# 声明继承 base.html #}
      
      
      {% block title %}
          <title>首页 - 我的网站</title> {# 覆盖母版中的 title 块 #}
      {% endblock %}
      
      
      {% block content %}
          <h2>欢迎阅读我们的最新文章</h2>
          {% archiveList articles with type="list" limit="5" %}
              <ul>
              {% for item in articles %}
                  <li><a href="{{ item.Link }}">{{ item.Title }}</a> - {{ stampToDate(item.CreatedTime, "2006-01-02") }}</li>
              {% endfor %}
              </ul>
          {% endarchiveList %}
      {% endblock %}
      
      
      {% block sidebar %}
          {# 完全覆盖母版侧边栏,只显示分类导航 #}
          <h3>文章分类</h3>
          {% categoryList categories with moduleId="1" parentId="0" %}
              <ul>
              {% for category in categories %}
                  <li><a href="{{ category.Link }}">{{ category.Title }}</a></li>
              {% endfor %}
              </ul>
          {% endcategoryList %}
      {% endblock %}
      

      通过这种方式,index.html 不再需要重复编写 <head><footer> 等公共代码,只需关注其特有的内容区域。

三、模板引用:插入独立的代码片段

模板引用适用于那些需要在多个页面或同一页面不同位置重复使用的独立代码片段,例如导航菜单、广告位、社交分享按钮等。它们通常是完整的、自包含的小模块。

  1. 核心理念: 模板引用就像是网站的“乐高积木”。每个积木都是一个功能完整的小模块,你可以根据需要在任何地方插入这些积木,即使多个地方都插入了同一个积木,它们也是独立的,互不影响。

  2. 如何使用 include 标签{% include "代码片段文件路径" %} 标签可以直接将另一个模板文件的内容插入到当前位置。

    • 定义代码片段 (partial/header.html): 假设 partial/header.html 包含网站的顶部导航:
      
      <nav class="top-nav">
          <a href="/">首页</a>
          <a href="/about">关于我们</a>
          <a href="/contact">联系方式</a>
          {# 使用navList标签获取动态导航菜单 #}
          {% navList main_navs %}
              {% for item in main_navs %}
                  <a href="{{ item.Link }}">{{ item.Title }}</a>
              {% endfor %}
          {% endnavList %}
      </nav>
      
    • 引用代码片段: 在 base.html 或其他任何需要显示导航的地方,直接使用 include
      
      <header>
          {% include "partial/header.html" %}
      </header>
      
    • 处理可选引用 (if_exists): 如果你不确定