模板标签的作用域、转义与调试

区分 djm:field、[field:] 和 djm:var 三种取值方式,理解循环作用域、raw 的边界,以及出错时怎么定位。

同一个字段名,在不同位置要用不同写法。字段用错作用域时不会报错,只会输出空值,这是模板调试里最常见的坑。

三种取值方式

  • {djm:field.title/}:读取当前页面实体。详情页是当前内容,栏目页是当前栏目。
  • [field:title/]:只在循环体内有效,读取最近一层循环的当前行。
  • {djm:var.search.keyword/}:页面级变量,例如搜索词、栏目单页正文。
{djm:list row="8"}
  <a href="[field:url/]">[field:title/]</a>
  <span>{djm:field.name/}</span>
{/djm:list}

上面这段在栏目列表页里,[field:title/] 是每条内容的标题,{djm:field.name/} 是当前栏目名。如果循环里把栏目名写成 [field:name/],引擎会去内容行里找 name 字段,结果为空。

循环嵌套时的作用域

循环内始终可以读到外层循环的字段,最近一层的同名字段优先。foreach 遍历对象列表时会把对象字段并入当前上下文,所以 category.images 这类结构也能直接用 [field:url/] 取图。

{djm:foreach from="category.images" as="pic"}
  <img src="[field:url/]" alt="[field:alt/]">
{/djm:foreach}

转义与 raw

所有输出默认做 HTML 转义。raw="1" 只对声明为富文本(rich_text)且已清洗的字段生效,普通标题、摘要、用户输入即使写了 raw 也仍然转义。

{djm:field.ext.body raw="1"}
{djm:field.summary len="80" default="暂无摘要"/}

图片不要手写 URL 拼接,用 {djm:img field="cover_image" output="img" alt="[field:title/]"/},它会补齐路径、输出宽高与懒加载属性。

条件与包含

if 支持 ==、!=、>、<、>=、<=,以及 and、or、not 和括号;表达式写错会在保存模板时被拒绝,不会等到线上空白。

{djm:if condition="field:cover_image != ''"}
  {djm:img field="cover_image" output="img" width="960"/}
{djm:else/}
  <span class="no-cover">暂无封面</span>
{/djm:if}

include 只接受主题根目录内的相对路径,/inc/head.html 和 ../ 都会被拒绝。

调试顺序

  • 先看模板编辑器保存时是否报错:未知标签、非法属性、错误排序值都会当场提示。
  • 输出为空先检查作用域:循环外用 [field:]、循环内用 {djm:field.} 都会拿不到值。
  • debug 开启时用 {djm:performance metric="db_reads"/} 看一次渲染读了几批数据,排查循环里重复取数。
  • 页面整体空白先看服务日志和健康检查,再怀疑反向代理缓存。

完整的标签签名、参数与示例见标签手册。

继续阅读

主题开发 首页、列表页、详情页的标签组合 主题开发 列表、分页与上下篇的进阶用法 主题开发 模板标签怎么用:从手册到页面组合 主题开发 主题结构、校验与打包发布

讨论