在AnQiCMS模板开发中,我们常常会遇到需要根据不同条件展示不同内容的情况。初学者可能会习惯性地大量使用{% if 条件 %}语句,随着项目需求的增长,这些条件判断层层嵌套,很快就会让模板变得难以阅读、维护,甚至隐藏潜在的逻辑错误。代码可读性一旦降低,不仅开发效率会受影响,日后的功能迭代和问题排查也会变得异常艰难。
幸运的是,AnQiCMS 基于 Go 语言的 Django-like 模板引擎提供了丰富的特性,我们可以利用这些工具来有效地避免if语句的过度嵌套,让模板代码保持清晰、优雅。
一、善用 set 和 with 声明变量,预处理复杂条件
减少if嵌套的第一步,是从源头简化条件本身。当条件表达式复杂或需要多次使用时,我们可以提前将其结果存储在一个变量中。AnQiCMS 模板支持{% set 变量名 = 值 %}和{% with 变量名 = 值 %}两种方式来定义变量。
例如,如果你需要判断一个文档是否是推荐、置顶且属于某个特定分类,传统的写法可能会这样:
{% if archive.Flag contains "c" and archive.Flag contains "h" and archive.CategoryId == 10 %}
{# 展示推荐置顶文章的特殊样式 #}
{% else %}
{# 普通文章样式 #}
{% endif %}
这样的条件既长又难以一眼看清。我们可以通过set或with将其分解:
{% set isSpecialRecommend = archive.Flag contains "c" and archive.Flag contains "h" and archive.CategoryId == 10 %}
{% if isSpecialRecommend %}
{# 展示推荐置顶文章的特殊样式 #}
{% else %}
{# 普通文章样式 #}
{% endif %}
这样,if语句的条件变得清晰简洁。set声明的变量在当前模板块内有效,而with则通常用于临时定义多个变量,并且需要用{% endwith %}结束。合理利用变量声明,能够有效提高条件判断的清晰度。
二、利用过滤器简化条件判断和数据展示
AnQiCMS 提供了丰富的过滤器(Filters),它们能对变量进行各种处理,很多时候可以替代简单的if/else逻辑。
default过滤器: 当变量可能为空时,为其提供一个默认值,避免冗长的if/else。{# 避免:{% if archive.Description %}{{ archive.Description }}{% else %}暂无描述{% endif %} #} {{ archive.Description|default:"暂无描述" }}yesno过滤器: 用于处理布尔值,根据真假输出指定文本。{# 假设 archive.IsPublished 是一个布尔值 #} {{ archive.IsPublished|yesno:"已发布,草稿,未知" }}length或直接判断: 检查列表、字符串、对象是否为空,避免{% if list|length > 0 %}。AnQiCMS 的模板引擎和 Django 类似,可以直接用
{% if 变量 %}判断集合或字符串是否非空。{# 避免:{% if tags|length > 0 %} #} {% if tags %} {# 标签列表不为空时 #} {% endif %}contain过滤器: 快速判断字符串或数组中是否包含某个关键词,无需手动遍历或复杂的字符串函数。{% if archive.Flag|contain:"c" %} {# 判断是否包含“推荐”标记 #} <span>推荐</span> {% endif %}
通过这些过滤器,很多简单的条件判断和数据格式化可以直接在变量输出时完成,模板中就不会出现那么多的if块了。
三、模块化模板,拥抱 include 和 macro
当一个复杂的if分支内部包含大量内容时,即使条件本身清晰,整个模板的体量也会变得庞大。这时,模块化是**实践。
include标签: 将模板的公共部分或复杂的分支逻辑抽取到单独的文件中。例如,如果你的文章详情页根据
Flag属性有多种展示模式,可以这样组织:{% if archive.Flag contains "f" %} {# 幻灯模式 #} {% include "partial/archive_layout_slideshow.html" with article=archive %} {% elif archive.Flag contains "a" %} {# 特荐模式 #} {% include "partial/archive_layout_featured.html" with article=archive %} {% else %} {# 默认模式 #} {% include "partial/archive_layout_default.html" with article=archive %} {% endif %}每个
partial/archive_layout_*.html文件只负责渲染自己的特定布局,主模板保持了简洁。with article=archive允许你向被包含的模板传递特定变量,避免全局污染,让模块更加独立和可复用。macro宏定义: 对于需要在多个地方重复使用的、带有特定逻辑的小段 HTML 结构,可以使用macro。宏可以像函数一样接收参数,封装内部逻辑。假设你在多个列表页都需要展示一个带有缩略图和标题的文章卡片,并且可能根据是否有缩略图来决定显示不同的样式:
”`twig {# 在 archive.helper.html 中定义宏 #} {% macro render_article_card(article) %}
{% if article.Thumb %} <img src="{{ article.Thumb }}" alt="{{ article.Title }}"> {% endif %} <h3><a href="{{ article.Link }}">{{ article.Title }}</a></h3> <p>{{ article.Description|