template.parsefiles 使用相对路径,需确认当前工作目录;自定义函数须用 funcs 注册且在 parse 前;{{define}} 仅注册模板,{{template}} 才执行;多文件解析时注意 {{define}} 顺序;html 转义可禁用。

template.ParseFiles 读不到文件?检查工作目录和路径拼写
Go 的 template.ParseFiles 是相对路径,它从当前进程启动目录(不是源码所在目录)开始找文件。很多人把模板放 templates/ 下,却在项目根目录外执行 go run main.go,结果报 open templates/main.tmpl: no such file or directory。
- 用
os.Getwd()打印当前工作目录,确认是不是你预期的位置 - 模板路径建议用绝对路径:先用
filepath.Join(filepath.Dir(runtime.Caller(0)), "templates", "main.tmpl")构造 - 如果用
go:embed,别混用 ——ParseFiles和ParseFS是两套逻辑,嵌入文件必须走text/template.ParseFS
模板里调用自定义函数时 panic: function "xxx" not defined
自定义函数必须显式通过 Funcs 注册,且注册要在 Parse 或 ParseFiles 之前。顺序错了,函数就不可见。
- 注册函数用
t.Funcs(template.FuncMap{"toUpper": strings.ToUpper}),注意t是 *template.Template 实例 - 函数签名必须是 Go 可导出的:首字母大写,参数和返回值类型要明确,不能有不定长参数(
...) - 如果函数返回 error,模板里不会自动捕获 —— 要自己判断:
{{if .Err}}{{.Err.Error}}{{else}}{{.Result}}{{end}}
嵌套模板 {{define}} / {{template}} 不生效?小心作用域和执行时机
{{define}} 只是注册一个命名模板,并不执行;{{template}} 才真正展开。常见错误是把 {{template "header"}} 放在 {{define "header"}} 上面,或者跨文件定义没统一 Parse。
- 所有
{{define}}必须在同一个template.Template实例中解析完成,否则{{template}}找不到目标 - 多个文件一起 Parse 时,后解析的文件能引用先解析的
{{define}},但反过来不行 —— 建议把基础模板(如base.tmpl)放在ParseFiles参数列表最前面 - 如果用
{{block}},它等价于{{define}} + {{template}}组合,但支持子模板覆盖,适合布局复用
生成代码时变量名冲突或转义过度?关掉默认 HTML 转义
text/template 默认对 {{.Var}} 输出做 HTML 转义(比如把 变成 <code>),生成 Go 代码、SQL、JSON 等纯文本时这会直接破坏语法。
立即学习“go语言免费学习笔记(深入)”;
- 用
{{.Var | printf "%s"}}或更干脆:改用text/template(不是html/template),它默认不转义 - 如果误用了
html/template,即使加| safeHTML也不安全 —— 它只信任template.HTML类型,对字符串无效 - 生成 Go 代码时,注意结构体字段必须导出(首字母大写),否则
{{.Field}}拿不到值,模板静默跳过
{{template}} 的参数传递容易漏掉上下文,特别是带 pipeline 的链式调用 —— 这时候别硬塞,拆成中间变量用 {{with}} 或提前构造好数据结构传进去。










