Revel母版页必须严格命名为app/views/layouts/main.html,用{{yield}}单独成行接收内容,子页面调用时必须传.且set赋值需在template前完成。

Revel 中母版页(layout)必须放在 app/views/layouts/ 下,用 {{yield}} 接收内容,且所有页面继承时必须传 .(当前上下文),漏掉点号会导致变量丢失、渲染为空。
母版页文件路径和命名必须严格为 app/views/layouts/main.html
Revel 不识别 Layout.html、base.html 或 app/views/main.html 这类变体。它只在 app/views/layouts/ 目录下查找名为 main.html 的文件作为默认母版页。若改名或挪动位置,{{template "layouts/main.html" .}} 会静默失败——页面空白,日志里只报 “template not found”,不提示缺的是哪一级路径。
- 不能写成
app/views/Layout.html:Revel 不会扫描根视图目录下的非layouts/文件 - 不能写成
app/views/layouts/Main.html:文件名区分大小写,Main.html≠main.html - 路径中的
layouts是硬编码关键词,不可替换成templates或shared
{{yield}} 必须单独成行,且第二个参数必须是 .
母版页中用于插入子页面内容的位置,只能用 {{yield}},不能用 {{.}}、{{template "content" .}} 或自定义 {{define "content"}}...{{end}} 来替代——后者仅适用于区块复用,不是 layout 机制的一部分。
-
{{yield}}必须独立一行,前后不能有 HTML 标签包裹,否则会被当成普通文本输出 - 子页面调用母版页时,
{{template "layouts/main.html" .}}的.绝对不能省略;写成{{template "layouts/main.html" nil}}或漏掉点号,会导致所有{{.title}}、{{.user}}等变量为空 -
{{yield}}不接受参数,也不支持指定区块名,它只接收子模板中未被{{define}}包裹的“默认内容”
子页面必须把 {{set . "key" "value"}} 放在最顶部
Revel 母版页读取 {{.title}}、{{.description}} 这类字段,依赖子页面在 {{template "layouts/main.html" .}} 之前就完成上下文赋值。一旦顺序颠倒,母版页拿到的就是空值。
- 正确顺序:
{{set . "title" "用户列表"}}{{template "layouts/main.html" .}} - 错误写法:先
{{template ...}}再{{set . ...}}——此时set生效在母版页渲染之后,无意义 - 如果需动态计算标题(如拼接用户名),必须在
set前完成逻辑,Go 模板不支持在set右侧写复杂表达式
公共区块(nav/footer)应放在 app/views/partials/ 并用 {{template}} 显式包含
母版页本身不应直接写导航或页脚 HTML,而应通过 {{template "partials/_nav.html" .}} 引入。这样修改一处,所有页面自动同步,避免漏改。
-
partials目录需手动创建在app/views/下,Revel 不自动生成 - 路径是相对于
app/views/的,所以partials/_nav.html是合法路径,./partials/_nav.html会失败 - 区块模板内仍可使用
{{.}}访问父级上下文,但要注意:若子页面未传.给母版页,partials也拿不到数据 - 动态年份推荐用
{{date "2006"}},别写死2026,避免每年手动更新
最容易被忽略的是 . 的传递时机和位置:它不是“有就行”,而是必须在 {{template}} 调用时原样带上,且子页面所有 set 操作必须在此之前完成——这两个约束共同决定了母版页能否真正“统一”起来。任何一环断开,就会出现部分页面标题正常、部分为空,或者导航栏渲染但用户信息丢失这类看似随机实则确定的问题。


















