同一个字段名,在不同位置要用不同写法。字段用错作用域时不会报错,只会输出空值,这是模板调试里最常见的坑。
三种取值方式
{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"/}看一次渲染读了几批数据,排查循环里重复取数。 - 页面整体空白先看服务日志和健康检查,再怀疑反向代理缓存。
完整的标签签名、参数与示例见标签手册。
讨论