Revel模板传参需同时满足Render方法传命名参数或导出结构体、字段首字母大写可导出、模板中用{{.x}}引用;嵌套字段和range遍历需注意导出与变量作用域;@url()要求参数名严格匹配路由定义且值不含斜杠。

Revel 模板传参不是“往模板里塞变量”那么简单,而是由 Render 方法决定上下文、由字段导出规则控制可访问性、由 {{.x}} 语法决定引用方式——三者缺一不可。传不进去、渲染为空、报 unexported field 错误,基本都卡在这三个环节。
Render 传参必须用命名参数或导出结构体
控制器里不能直接 c.Render(users),这样 .users 在模板里根本不存在。Revel 只认键值对形式的命名参数,或者导出的结构体实例。
- 推荐写法:
c.Render("users", users, "title", "用户列表")→ 模板中用{{.users}}和{{.title}} - 结构体传参:定义
type PageData struct { Users []User; Title string }(字段首字母大写!),然后c.Render("data", PageData{Users: users, Title: "用户列表"})→ 模板中用{{.data.Users}} - 错例:
c.RenderArgs["users"] = users虽然能用,但绕过类型检查,容易拼错键名且 IDE 无提示
模板里访问嵌套字段前先确认结构体和字段都导出
Go 模板靠反射读取字段,未导出字段(小写字母开头)一律不可见。常见错误是 company []Company 写成 company []company,后者连类型名都不导出。
- 结构体类型名必须大写:
type Company struct { Name string },不能是type company struct - 字段名必须大写:
Name string,不能是name string - 切片字段也得导出:
Companies []Company,不是companies []Company - 错误信息典型提示:
company is an unexported field of struct type interface{}
range 遍历切片时索引和元素必须显式声明为 $ 变量
写 {{range .Users}} 只能得到当前元素,拿不到索引;想把索引传给子模板,必须用双变量解构,且变量名前加 $。
- 正确:
{{range $i, $u := .Users}} {{template "user.html" $i}} {{end}} - 错例1:
{{range $i, u := .Users}}——u没加$,在嵌套模板里可能被覆盖 - 错例2:
{{range .Users}} {{.ID}} {{.Name}} {{template "user.html" $i}}——$i在这个作用域里根本未定义 - 注意:
.在range块内自动指向当前元素(即$u),不是原始数据对象
@url() 生成带路径参数的 URL 时参数名必须严格匹配路由定义
@url() 不校验参数是否存在或是否合法,只做字符串替换。传错名、传斜线、大小写不一致,都会导致生成的 URL 无法匹配路由。
- 路由定义是
GET /hotels/:id Hotels.Show,模板里就得写@url("Hotels.Show" "id" 123),不能写"ID"或"hotel_id" - 参数值不能含
/,因为:id的匹配规则是“除斜杠外任意字符”,@url("Hotels.Show" "id" "123/abc")会生成/hotels/123/abc,路由根本不认 - 整数参数会被自动转成字符串,所以
123和"123"效果一样,但别传nil或空字符串,否则生成/hotels/这种非法路径
最常被忽略的是结构体字段导出规则和 @url() 的静默失败——它不报错,只生成一个永远 404 的链接,排查时容易绕远路。写完模板,务必用真实数据跑一遍,而不是只看编译是否通过。


















