登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  Golang >  Go教程

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 说明图:普通文本、[[动作]]边界与数据字段的关系
图1:Go html/template 的分隔符边界说明图,展示普通文本与 [[动作]] 的区分。

在 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 的安全转义

测试时最好同时放一段新语法和一段旧语法,验证“新语法执行、旧语法保留”这一明确结果。不要只看页面是否出现文字,因为字段为空和动作未解析都可能表现为内容缺失。

Go html/template Delims 结构图:Delims 配置流向 Parse 与 Execute 的边界
图2:Delims、Parse 与 Execute 的调用关系结构图,强调设置时机和执行阶段的边界。

处理多次解析与模板集合

同一个模板对象调用 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 的上下文转义规则决定。

左右分隔符可以设置成相同字符串吗?

不建议这样设计。左右边界应清晰可区分,否则模板阅读和错误定位都会变困难;优先选择成对且不与正文冲突的标记。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>