Go html/template Delims 怎样切换模板动作分隔符
来源:17golang原创
时间:2026-10-27 19:56:53 352浏览 收藏
Go 的 html/template 默认把 {{ 和 }} 当作动作边界。如果模板本身要展示这类字符,或者与另一套模板语法嵌套,就可以在解析前调用 Delims 换成一组不冲突的分隔符,例如 [[ 与 ]]。关键点只有一个:先设置分隔符,再调用 Parse、ParseFiles 或 ParseFS;它不会改写普通文本,也不会把旧分隔符自动转换为新语法。
官方文档:https://pkg.go.dev/html/template#Template.Delims
Delims(left, right)只决定模板动作的边界。- 自定义分隔符必须在相关模板解析前设置。
- 旧的
{{.Name}}在新分隔符模式下会按普通文本处理。
先区分普通文本与模板动作
Delims 修改的是模板引擎寻找动作的规则。比如把分隔符改成 [[ 与 ]] 后,[[.Name]] 会绑定数据,而 HTML 文本中的 {{ example }} 仍会原样保留。这个特性适合模板文件同时包含前端占位符、文档示例或另一种渲染语法的场景。
分隔符应选择不会出现在普通内容中的短字符串。它不是 HTML 转义开关,也不负责处理用户输入;输出仍由 html/template 按上下文进行安全转义。
![Go html/template Delims 说明图:普通文本、[[动作]]边界与数据字段的关系](/uploads/20261027/1793102212-510185f0a1-9db7444013-go-html-template-delims-boundary.webp)
在 Parse 前设置 Delims
下面的例子把动作边界改成方括号。代码中的中文注释说明设置顺序和错误处理;真正的模板字符串只使用新分隔符。
package main
import (
"os"
"html/template"
)
func main() {
// 先设置动作分隔符,再解析模板文本。
tmpl, err := template.New("page").Delims("[[", "]]").Parse(
`[[.Title]]
{{ 保留为普通文本 }}`,
)
if err != nil {
// 解析阶段的错误要立即返回,避免执行未完成的模板。
panic(err)
}
// 执行阶段只替换新分隔符中的字段,普通文本不参与绑定。
if err := tmpl.Execute(os.Stdout, struct{ Title string }{Title: "Delims 示例"}); err != nil {
// Writer 或字段执行错误都应交给调用方处理。
panic(err)
}
}
这里的 {{ 保留为普通文本 }} 不会触发模板解析,因此它会出现在输出中。若把它误认为旧模板语法并期待执行,排查方向应回到分隔符配置,而不是修改数据结构。
用最小模板验证执行结果
可以用下面的检查表判断问题发生在哪一层:
| 现象 | 优先检查 | 边界结论 |
|---|---|---|
[[.Title]] 原样输出 | 是否在 Parse 前调用 Delims | 解析时没有采用新分隔符 |
{{.Title}} 原样输出 | 模板是否仍处于自定义分隔符模式 | 旧语法不会自动迁移 |
| Parse 报语法错误 | 左右分隔符是否成对、正文是否完整 | 这是模板文本问题,不是 Execute 问题 |
| 字段值被转义 | 输出上下文和输入类型 | Delims 不改变 html/template 的安全转义 |
测试时最好同时放一段新语法和一段旧语法,验证“新语法执行、旧语法保留”这一明确结果。不要只看页面是否出现文字,因为字段为空和动作未解析都可能表现为内容缺失。

处理多次解析与模板集合
同一个模板对象调用 Delims 后,后续解析操作会使用新的边界。因此在 ParseFiles、ParseGlob 或 ParseFS 组成模板集合时,应先确定整组文件的语法约定,再统一设置。若一部分文件使用 {{ }}、另一部分使用 [[ ]],不要期待一次解析同时理解两套动作边界;更稳妥的做法是拆成不同模板集合或先统一文件内容。
若代码需要反复构造模板,可以把分隔符放在构造函数内,而不是依赖调用方记住顺序。这样也便于测试:每个模板集合都能明确写出自己的语法契约。
func parsePage(src string) (*template.Template, error) {
// 构造阶段固定一套语法,避免不同调用路径混用默认分隔符。
return template.New("page").Delims("[[", "]]").Parse(src)
}
按场景选择分隔符并保留边界
选择分隔符时优先考虑源文件中已经存在的字符、团队可读性和迁移成本。分隔符太长会增加模板噪声,太常见则容易误触发。它只解决“模板动作与正文语法冲突”这一问题,不能替代 HTML 安全转义、输入校验、权限判断或业务层数据清洗。
如果只想输出一段字面量模板语法,可以评估转义或拆分文本是否更简单;如果整套模板都要避开默认动作边界,再使用 Delims。保持一个模板集合只使用一套约定,通常比在运行时频繁切换更容易维护。
常见问题
Delims 设置后为什么还是识别旧的双大括号?
检查旧模板文本是否在设置前已经 Parse。Delims 不会回写已经解析的模板树,也不会自动转换旧语法。
Delims 能否解决模板中的 HTML 安全问题?
不能。它只改变动作边界,安全输出仍由 html/template 的上下文转义规则决定。
左右分隔符可以设置成相同字符串吗?
不建议这样设计。左右边界应清晰可区分,否则模板阅读和错误定位都会变困难;优先选择成对且不与正文冲突的标记。
-
409 收藏
-
464 收藏
-
125 收藏
-
428 收藏
-
226 收藏
-
220 收藏
-
113 收藏
-
235 收藏
-
202 收藏
-
424 收藏
-
372 收藏
-
237 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习