Revel模板必须用layouts+partials两级拆分实现复用:在layouts/main.html中用{{yield .}}注入内容,partials/_nav.html等片段通过{{template "partials/_nav.html" .}}调用,子模板以{{define}}声明区块并继承layout。

Revel 模板里不能靠复制粘贴来复用 header、footer 或导航栏——改一处就得翻十个文件,漏一个就线上不一致。必须用 layouts + partials 两级拆分,这是唯一能长期维护的写法。
创建 layouts/main.html 并用 {{yield}} 插入内容
在 app/views/layouts/main.html 中写标准 HTML 结构,关键点是:{{yield}} 必须存在且不带任何额外参数,它是子模板内容的唯一注入点。
常见错误:漏掉点号,比如写成 {{yield}} 而不是 {{yield .}}(注意 Revel 0.19+ 要求显式传参);或者把 {{yield}} 放在 外面导致 CSS/JS 加载失败。
-
{{yield}}只能出现一次,且必须在内部 - 所有公共资源引用(
<link>、<script></script>)都应放在这里,避免子模板重复引入 - 如果子模板需要动态 title,得在子模板开头用
{{set . "title" "首页"}},然后在main.html的<title></title>标签里写{{.title}}
把导航、页脚等抽成 partials/_nav.html 和 partials/_footer.html
partials 目录专用于存放可被多次 template 包含的片段。这些文件本身不渲染,只提供 HTML 块。
例如 app/views/partials/_nav.html:
{{if .CurrentUser}}
<nav class="navbar"><ul><li>首页</li><li>用户中心</li></ul></nav>
{{else}}
<nav class="navbar"><ul><li>首页</li><li>登录</li></ul></nav>
{{end}}
注意:{{template "partials/_nav.html" .}} 必须传入 .,否则 .CurrentUser 等上下文变量取不到值。
- 不要在
partials文件里写{{define}}—— 它们不是布局,只是纯 HTML 片段 - 命名统一加下划线前缀(如
_nav.html),避免和页面模板名冲突 - 日期类动态内容(如版权年份)直接用
{{date "2006"}},别硬编码
在页面模板中继承 layout 并填充 define 区块
以 app/views/App/Index.html 为例,结构必须是三段式:
第一段:设置元信息(必须最前){{set . "title" "首页"}}{{set . "description" "欢迎来到主页"}}
第二段:声明继承关系{{template "layouts/main.html" .}}
第三段:定义各区块内容(顺序无关,但必须在 template 调用之后)
{{define "header"}}<h1>首页</h1>{{end}}<br>
{{define "content"}}<p>这里是正文</p>{{end}}<br>
{{define "footer"}}{{template "partials/_footer.html" .}}{{end}}
关键限制:{{define}} 块内不能混写未包裹的 HTML —— 所有内容必须在 {{define}} / {{end}} 之间,否则会被忽略。
- 如果某个页面不需要某区块(如无侧边栏),就别写对应的
{{define "sidebar"}} -
{{define}}名称要和main.html里预留的占位一致,比如main.html里写了{{template "header" .}},那子模板就必须用{{define "header"}} - 区块内可以嵌套
{{template "partials/xxx.html" .}},但不能递归调用自身
为什么不能直接在子模板里 template partials?
可以,但容易失控。比如每个页面都写 {{template "partials/_nav.html" .}},看似简单,实则埋下三个坑:
- 导航逻辑分散:权限判断、高亮状态、菜单生成规则散落在多个文件里,改个“用户中心”入口就得查 8 个地方
- 上下文污染风险:某个页面忘了传
.,_nav.html里.CurrentUser就是 nil,模板静默渲染为空,很难排查 - 无法统一拦截:想给所有导航加 data-track 属性?得逐个改;而放在
main.html的{{template "partials/_nav.html" .}}外面包一层<div data-layout="nav">...</div>就全局生效
真正该被直接 template 的,只有那些完全静态、零逻辑、纯展示的片段(比如一个 SVG 图标)。只要带条件、依赖上下文、或未来可能变化,就该收进 layout 的 {{define}} 流程里。


















