在AnQiCMS中,模板引擎扮演着核心角色,它负责将后端动态获取的数据,以我们预设的布局和样式展示给访问者。理解其支持的语法结构,就像掌握了与网站内容“对话”的语言,能够让我们灵活地控制信息的显示方式,从而打造出高度个性化和动态化的网站体验。

AnQiCMS的模板引擎采用了类似于Django模板引擎的语法风格,这使得无论是Go语言开发者还是熟悉其他模板语言的用户,都能够比较容易地掌握。它通过一系列直观的标签和过滤器,帮助我们轻松实现内容的动态展示。

动态数据的引用与展示

最基础也是最常用的语法,莫过于通过双花括号来引用动态数据。当我们需要在模板中显示从数据库或其他地方获取的变量值时,只需使用 {{变量名}} 这样的格式。例如,要显示一篇文档的标题,我们可以写 {{archive.Title}};显示网站名称则是 {{system.SiteName}}。这些变量通常遵循驼峰命名法,首字母大写,使得代码可读性更强。这种直接引用变量的方式,使得静态的HTML骨架瞬间充满了生命力,能够根据实际数据自动更新。

条件判断与逻辑控制

仅仅显示数据是不够的,很多时候我们需要根据不同的条件来显示不同的内容块。这时,{% if ... %} 标签就显得尤为重要。它允许我们基于变量的值进行逻辑判断。例如,判断一个列表是否为空,或者某个特定字段是否满足某个条件。

基本的用法是 {% if 条件 %} ... {% endif %}。如果需要更复杂的逻辑,可以引入 {% elif 其他条件 %}(else if的缩写)来处理多个互斥的条件,以及 {% else %} 作为所有条件都不满足时的备选方案。例如,我们可以判断用户是否登录来显示不同的导航菜单,或者根据文章是否有缩略图来决定是否显示图片占位符。这种结构使得模板能够像程序代码一样,根据运行时的数据做出智能的响应。

循环遍历与列表展示

网站内容往往以列表的形式呈现,比如文章列表、产品列表、分类导航等。AnQiCMS模板引擎提供了 {% for ... in ... %} 标签来高效地遍历数组或切片类型的数据。在循环体内部,我们可以访问当前迭代项的属性,并将其展示出来。

值得一提的是,for 循环还支持一些非常实用的辅助功能。例如,{% empty %} 标签可以在列表为空时,显示一段预设的内容,避免页面出现空白或错误。此外,forloop.Counter 可以获取当前循环的索引(从1开始),forloop.Revcounter 则获取倒序索引,这些都可以用来为列表项添加独特的样式或行为。如果你需要按特定顺序(如反向)遍历列表,reversed 关键词可以直接在 for 标签中使用,而 sorted 标签(如果有支持)则可以帮助你按特定规则排序。这些功能极大地提升了列表内容展示的灵活性。

数据处理与格式化过滤器

原始数据可能不总是符合我们展示的需求,例如时间戳需要格式化为可读的日期,长文本需要截断,或者HTML内容需要安全地输出。过滤器(Filters)就是为此而生。它们通过 {{变量|过滤器名称:参数}} 的形式,对变量进行处理后再输出。

一些非常实用的过滤器包括:

  • stampToDate: 这是AnQiCMS特有的过滤器,用于将时间戳格式化为各种日期时间字符串,如 {{item.CreatedTime|stampToDate:"2006-01-02"}}
  • safe: 当变量内容包含HTML代码,并且我们希望浏览器将其作为HTML解析而不是显示为纯文本时,需要使用 |safe。这在展示富文本编辑器输出的文章内容时尤为关键,但使用时需确保内容来源安全,以防XSS攻击。
  • truncatechars/truncatewords: 用于截断过长的字符串或HTML内容,并自动添加省略号,常用于生成文章摘要。
  • add: 可以进行简单的数学加法或字符串拼接,例如 {{price|add:discount}}
  • default/default_if_none: 当变量没有值(空字符串、零、nil等)时,提供一个默认的显示值,避免页面出现空白。
  • length: 获取字符串、数组或映射的长度。
  • escapejs: 用于将字符串安全地嵌入到JavaScript代码中,避免语法错误或注入问题。

这些过滤器构成了模板中强大的数据处理能力,让我们能够以最优雅的方式呈现数据。

模板结构与复用机制

为了提高模板的可维护性和开发效率,AnQiCMS模板引擎提供了多种结构化和复用机制:

  • {% include "文件路径" %}: 用于将一个模板文件中的内容插入到另一个模板中。这非常适合复用页头、页脚、侧边栏等小块内容。
  • {% extends "基础模板" %}: 实现模板继承。我们可以定义一个包含网站通用结构(如HTML头部、导航、页脚等)的基础模板,并在其中使用 {% block 块名 %} 定义可重写区域。其他模板只需继承这个基础模板,然后重写需要自定义的块,大大减少了重复代码。
  • {% macro 宏函数名(参数) %} ... {% endmacro %}: 允许我们定义可重用的代码片段,这些宏可以像函数一样被调用,并且可以被导入到其他模板中,提供高度的模块化。
  • {% with 变量名=值 %}{% set 变量名=值 %}: 这两个标签用于在模板中定义局部变量。with通常与include结合使用,为被包含的模板传递特定参数;set则用于在当前模板块内临时定义变量。

特定功能的数据标签与辅助标签

除了通用的逻辑控制和结构标签,AnQiCMS还内置了大量针对特定功能的数据标签,极大地简化了数据获取的复杂度:

  • {% system 变量名 %}: 获取网站全局设置,如网站名称、Logo、备案号等。
  • {% contact 变量名 %}: 方便地获取后台配置的联系方式信息。
  • {% archiveList 变量名 %}: 获取文章或产品列表,支持按分类、模型、推荐属性、排序方式等多种条件筛选,甚至支持分页。
  • {% categoryList 变量名 %}: 获取分类列表,支持多级分类嵌套。
  • {% pageList 变量名 %}: 获取单页面列表。
  • {% pagination 变量名 %}: 配合 archiveList 等分页标签,方便地生成分页导航链接和状态。

这些标签将复杂的数据库查询逻辑封装起来,让我们可以在模板中以声明式的方式获取所需数据,无需关心底层实现细节。

最后,还有一些细节控制标签,如 {%--%} 用于精确控制模板输出中的空白字符,避免不必要的空行或空格,使生成的HTML更整洁。而 {% lorem %} 标签则可以在模板开发阶段,快速生成占位用的随机文本,方便布局调试。

AnQiCMS的模板引擎提供了从基础数据展示到复杂逻辑控制,再到模板结构化复用的全面语法支持。掌握这些语法,能够让我们游刃有余地驾驭网站内容的动态显示,为访客提供丰富且交互友好的浏览体验。


常见问题 (FAQ)

1. 为什么我在模板中引用的变量没有显示内容,或者显示为空? 这通常有几个原因:

  • 变量名拼写错误: 模板变量是大小写敏感的,请仔细检查变量名是否与文档或后端提供的数据结构完全一致。例如,archive.titlearchive.Title 是不同的。
  • 数据未传递到模板: 确保后端逻辑已经正确获取了数据,并将其传递给了当前渲染的模板。如果是在archiveListcategoryList等循环中,要确保循环本身有数据。
  • 数据为空或不存在: 有时变量可能确实没有值(例如文章没有缩略图),此时可以考虑使用 |default:"默认值" 过滤器来提供一个备用显示。
  • 作用域问题: 特别是在includemacro中使用变量时,如果未使用with传递变量或only限制作用域,可能导致变量不可用。

2. 我可以在AnQiCMS模板中直接执行复杂的编程逻辑或数据库查询吗? 不建议直接在模板中执行复杂的编程逻辑或数据库查询。AnQiCMS模板引擎的设计理念是“逻辑与表现分离”,它主要关注内容的展示而非业务逻辑处理。复杂的业务逻辑和数据查询应该在后端(控制器/模型)完成,然后将处理好的、结构化的数据传递给模板。模板中的iffor和过滤器用于基本的控制流和数据格式化。这样做的好处是提高代码可维护性、测试性,并确保模板的安全性。如果模板中需要的数据不满足,应优先考虑调整后端数据提供方式,或使用内置的数据标签(如archiveList等)进行获取。

3. 如何确保模板输出的安全性,防止XSS攻击? AnQiCMS模板引擎默认会对所有通过 {{变量}} 输出的内容进行HTML实体转义,这可以有效防止大部分