Shopify JSON template 怎么写?Dawn 自定义页面模板实测
Shopify JSON template 看起来只是一个 JSON 文件,但真正容易出错的不是括号,而是 sections、order、Section 文件和模板命名之间没有对应好。本文用 Dawn 16.0.0 的本地副本新建一个备用页面模板,并用静态断言和 Shopify CLI Theme Check 检查结果。
这次只修改本地主题副本,没有上传主题、分配页面或改动在线商店。实测前,原始 Dawn 共检查 156 个文件,得到 11 个既有 warning;加入新模板后检查 157 个文件,仍是相同的 11 个 warning,说明本次模板没有引入新增问题。
Shopify JSON template 负责什么
JSON template 本身不写页面 HTML,它保存要渲染的 Section、每个 Section 的设置,以及它们的顺序。真正输出 HTML 和 Liquid 的仍是 sections/*.liquid 文件。商家在主题编辑器里添加、删除或拖动 Section,最终修改的也是模板中的这类结构。
如果还没理清 layout、template、section 和 snippet 的关系,可以先看Shopify Dawn 主题目录结构和Shopify Section 和 Block 入门。JSON template 位于 templates/,作用更像一份“页面装配清单”。
先看 Dawn 默认 page.json
Dawn 16.0.0 的 templates/page.json 很简单,只引用一个 main-page Section:
{
"sections": {
"main": {
"type": "main-page",
"settings": {
"padding_top": 28,
"padding_bottom": 28
}
}
},
"order": ["main"]
}
这里的 main 是当前模板内的 Section ID,main-page 才是文件类型,对应 sections/main-page.liquid。ID 可以自己命名,但只能使用字母和数字,而且同一模板内不能重复。
新建一个备用页面模板
为了不覆盖默认页面模板,我新建了 templates/page.field-notes.json。文件名中的 field-notes 是 template suffix;以后把主题上传到商店后,可以把这个备用模板分配给某个页面,而不影响继续使用 page.json 的其他页面。
{
"wrapper": "main#MainContent.content-for-layout.focus-none",
"sections": {
"main": {
"type": "main-page",
"settings": {
"padding_top": 28,
"padding_bottom": 28
}
},
"notes": {
"type": "rich-text",
"disabled": true,
"settings": {
"desktop_content_position": "center",
"content_alignment": "left",
"color_scheme": "scheme-1",
"full_width": true,
"padding_top": 40,
"padding_bottom": 52
}
}
},
"order": ["main", "notes"]
}
这个例子保留了显示页面标题和正文的 main-page,另外引用 Dawn 已有的 rich-text,但先把它设为 disabled: true。这样 Section 的配置仍保存在模板中,却不会输出到页面;以后在主题编辑器里启用并填写内容即可。
sections 和 order 必须互相对应
sections 是对象,保存每个 Section 的类型、设置和 Block;order 是数组,决定 Section 的渲染顺序。两者必须同时满足以下条件:
order中的每个 ID 都能在sections中找到。- 同一个 ID 不能在
order中出现两次。 - 普通 Section 的
type必须能找到对应的sections/type.liquid文件。 - 想在主题编辑器里动态添加的 Section,通常需要在自身 schema 中提供
presets。
我对新模板做了本地断言:JSON 能解析、两个 Section ID 都出现在 order 中、两个 Section 文件都存在、备用模板文件名有效,并且 notes 的禁用状态确实为布尔值 true。这几项全部通过。
wrapper 是可选项,不要重复页面主区域
wrapper 可以给模板中的全部 Section 增加一个统一外层。本次写成 main#MainContent.content-for-layout.focus-none,会得到带 ID 和 class 的 <main> 容器。Shopify 当前允许的 wrapper 标签包括 div、main 和 section。
不过,是否应该添加 main 不能只看 JSON 是否通过。还要检查 layout/theme.liquid 是否已经在 {{ content_for_layout }} 外层提供主区域,避免最终页面出现重复的 <main> 或重复 ID。本文保留该字段是为了展示语法;迁移到其他主题时应按实际布局调整或直接省略。
Theme Check 前后结果怎么判断
我先检查未修改的 Dawn,再检查加入备用模板后的副本:
shopify theme check --path ./dawn-current
# 156 files inspected
# 11 warnings
shopify theme check --path ./theme-test
# 157 files inspected
# 11 warnings
两次检查的 warning 都来自 Dawn 原有的 8 个文件,包括变量命名、未使用变量和对象识别提示;新建的 page.field-notes.json 没有出现在问题列表中。这里不能简单写成“Theme Check 有 warning,所以模板失败”,也不能忽略基线直接宣称“零问题”。更准确的结论是:新增一个文件,warning 数量和来源没有变化,本次修改没有引入新增 offense。
Theme Check 的安装、warning 与 CI 阈值可以参考Shopify Theme Check 使用教程。
常见错误怎么排查
- order 找不到 Section:检查大小写、拼写,以及 ID 是否只存在于
order而没有写进sections。 - Section type 不存在:确认
type: "rich-text"对应的是sections/rich-text.liquid,不要把 Section ID 当成文件名。 - 主题编辑器里无法添加:检查 Section schema 是否包含
presets,以及enabled_on或disabled_on是否限制了模板类型。 - 备用模板找不到:确认命名为
template-name.template-suffix.json,例如page.field-notes.json,并确认模板已经上传到当前主题。 - 修改影响了多个页面:检查这些页面是否共用同一个模板。主题编辑器中的 Section 结构属于模板,不是单个页面的私有副本。
上传和分配前的实际检查顺序
- 在本地主题副本中创建备用模板,不直接改在线主题。
- 解析 JSON,并核对
sections、order和 Section 文件。 - 记录修改前 Theme Check 基线,再检查修改后的结果。
- 把主题上传为草稿主题,先在主题编辑器中预览备用模板。
- 确认标题、正文、Section 顺序、移动端和应用区块正常后,再把模板分配给目标页面。
第 4、5 步涉及真实商店状态,本次没有执行,因此不把它们写成实测结果。草稿主题如何预览,以及主题编辑器里模板、Section 和 Block 如何对应,可以继续看Shopify 草稿主题预览教程和Shopify 主题编辑器使用教程。
本次实测结论
Shopify JSON template 的核心不是把页面 HTML 塞进 JSON,而是用固定结构声明“有哪些 Section、各自是什么类型、按什么顺序渲染”。这次在 Dawn 16.0.0 中增加 page.field-notes.json 后,文件数从 156 变成 157,Theme Check 仍保持 11 个既有 warning;本地结构断言和 Shopify 主题文件验证也全部通过。
实际项目中,我会先创建备用模板并保留默认模板,再经过本地检查、草稿主题预览和页面分配三道确认。这样即使 Section 配置需要继续调整,也不会先把所有共用默认模板的页面一起改掉。
官方资料:JSON templates、Alternate templates、Templates、Theme limits(访问日期:2026 年 9 月 8 日;实测环境:Dawn 16.0.0、Shopify CLI 4.7.1)。




