revel模板路径必须严格匹配控制器名大小写和嵌套层级,layout.html须置于app/views/根目录且命名精确,嵌套模板路径始终相对于views根目录,多级传参需显式传递。

Revel模板路径必须严格匹配控制器名大小写和嵌套层级
Revel不支持通配符加载或自由指定路径,所有视图文件必须放在app/views/下,且目录结构必须与控制器包名、类型名完全一致。比如控制器app/controllers/Admin.go中定义了type Admin struct{ *revel.Controller },那它的模板就必须放在app/views/Admin/目录下,不能是app/views/admin/或app/views/AdminUser/。
常见错误现象:页面空白或404,但控制台无报错;原因是Revel按约定路径查找模板,路径错一位、大小写差一个字母,就直接跳过渲染。
- 控制器
app/controllers/User/Profile.go→ 模板路径必须是app/views/User/Profile/(注意User和Profile首字母大写) - 多级包如
app/controllers/Api/V1/Users.go→ 模板路径为app/views/Api/V1/Users/,不是app/views/api/v1/users/ - 若控制器在
app/controllers/平级,没有子包,则模板只能放app/views/ControllerName/,不能进更深的子目录
Layout.html只认首字母大写的根目录布局文件
Revel对布局模板有硬性命名和位置要求:Layout.html必须放在app/views/根目录下,且文件名必须是Layout.html(首字母大写,后缀小写),不能叫layout.html、base.html或app/views/shared/Layout.html。
这个文件会被自动注入到所有模板的{{ yield }}位置,但前提是它存在且路径/大小写完全正确。如果放错位置或改名,Revel不会报错,只是跳过布局,直接渲染内容模板——导致样式丢失、结构断裂。
- 正确路径:
app/views/Layout.html - 错误路径:
app/views/layouts/Layout.html、app/views/layout.html、app/views/Shared/Layout.html -
{{ yield }}必须出现在Layout.html里,且不能写成{{yield}}(少空格)或{{ .yield }}(加点号)
嵌套模板调用时路径是相对于views根目录的
Revel中{{ template "path/to/partial.html" . }}里的字符串,是完整路径(不含app/views/前缀),且区分大小写、严格匹配文件系统路径。它不是相对当前模板所在目录,而是始终从app/views/开始算起。
例如你在app/views/Admin/Dashboard/index.html里想嵌入页脚,得写{{ template "partials/footer.html" . }},而不是{{ template "../partials/footer.html" . }}——后者Revel根本不认识。
- 假设你有
app/views/partials/header.html,任何模板里都统一用{{ template "partials/header.html" . }} - 若误写成
{{ template "Partials/header.html" . }}(P大写),Linux/macOS下会404;Windows下可能侥幸通过,但部署到生产环境必挂 - Revel不会自动补全后缀,
{{ template "partials/header" . }}会报template: "partials/header" is undefined
多级目录下传参必须显式传递,不能依赖作用域链
Revel模板的作用域是扁平的,嵌套模板之间不共享父模板的.上下文。即使你在Admin/List.html里用{{ template "Admin/item.html" . }},子模板item.html拿到的仍是整个传入对象,不会自动“继承”外层range的当前项。
容易踩的坑是:在外层{{range .Users}}里调用{{ template "Admin/item.html" . }},结果子模板里{{.Name}}取不到值——因为.还是原始结构体,不是当前用户。
- 正确做法:显式传入当前项,例如
{{ template "Admin/item.html" $ }}($代表根上下文)或{{ template "Admin/item.html" .User }} - 若需同时传当前项+索引,用双变量
{{range $i, $u := .Users}},再{{ template "Admin/item.html" (dict "User" $u "Index" $i)}} - 注意:
dict函数需在app/init.go中手动注册,否则报function "dict" not defined
template not found提示,而是直接返回空响应或原始HTML文本。











