Revel模板需显式传参、严格上下文管理:c.Render()传值,结构体字段首字母大写,nil切片须判空;range遍历须用{{$i,$u:=.list}}取索引与元素;field函数依赖控制器调用Validation.Error;{{yield}}与{{template}}不可混用。

Revel 模板不是“写完就能用”的静态 HTML,它依赖明确的传参、正确的函数调用和严格的上下文管理——漏掉一个点号、拼错一个字段名、忘记判空,页面就可能空白或 panic。
模板怎么接收控制器传来的数据?
必须用 c.Render() 显式传参,且变量名要能被模板直接引用。传结构体时字段必须首字母大写;传 map 或命名参数更安全。
- 推荐写法:
c.Render("title", "用户列表", "users", users)→ 模板中用{{.title}}和{{.users}} - 结构体字段未导出(如
name string)会导致{{.name}}渲染为空,不报错 - 若传
nil切片,后续直接{{range .users}}会 panic,必须先{{if .users}}
怎么安全遍历切片并拿到索引?
Go 模板的 range 不自动提供索引,必须用双变量绑定,且变量名前加 $ 防止作用域污染。
- 正确写法:
{{range $i, $u := .users}}序号: {{$i}}, 名字: {{$u.Name}}{{end}} -
$i是 int 类型索引,$u是当前元素;.在块内等于$u,但不等于$i - 若需把索引传给子模板,必须显式传参:
{{template "item.html" $i}}或{{template "item.html" (dict "index" $i "user" $u)}}(后者需提前注册dict函数)
表单渲染和校验为什么总不生效?
Revel 的 field 函数不是“自动魔法”,它依赖控制器里已触发的验证逻辑和错误注入。
-
{{with $f := field "user.Email" .}}{{input $f}}{{end}}只有在控制器调用了c.Validation.Error("user.Email")后,$f.Error才非空 -
field生成的name、id、value全部来自你传入的字段路径字符串,拼错路径(如写成"email"而非"user.Email")会导致值无法绑定 - 表单提交后字段为空,大概率是控制器方法签名没对上:例如
Create(email string)中参数名必须和表单name="email"一致
布局复用和区块嵌套为什么内容不显示?
{{yield}} 和 {{template}} 行为完全不同,混用会导致内容丢失或静默忽略。
-
{{yield "content" .}}是 layout 模板里的“占位符”,只在被{{template "layouts/main.html" .}}包裹的页面中,用{{define "content"}}...{{end}}填充才生效 -
{{template "partials/_nav.html" .}}是立即加载并渲染子模板,路径必须相对于app/views/,且不能写成../partials/... - 常见错误:
{{define "header"}}{{template "partials/_nav.html" .}}{{end}}写在了{{template "layouts/main.html" .}}外面 —— 这段define根本不会被 layout 捕获
最易被忽略的一点:所有模板函数(eq、set、append、field)都只在当前模板作用域生效,子模板不自动继承父模板里 set 的变量;跨模板传值必须靠 {{template "x" .}} 或显式参数传递。











