Revel 模板内置函数足够日常使用:eq 判断、set 定义变量、append 拼切片;field 处理表单绑定与校验;revel.Message/T 实现多语言;自定义函数须在 app/init.go 的 init() 中注册且重启生效。

模板里直接用 eq、set、append 就够了,别急着写自定义函数
Revel 内置的模板函数覆盖了 80% 的日常需求,eq 做判断、set 定义局部变量、append 拼切片,全都不用注册、不重启、不写额外代码。比如渲染页头标题:{{set ."pageTitle" "用户列表"}},后续直接 {{.pageTitle}};判断状态用 {{if eq .Status "active"}},它比原生 == 更宽松,int 和 string 都能比(比如 .Code 是 int,但写 {{if eq .Code "200"}} 也能过)。
常见错误是以为必须写自定义函数才能做字符串处理——其实大可不必。小写转大写、截取长度、格式化时间这些,都该先查内置函数是否支持,而不是一上来就去 init.go 注册。
field 函数才是表单场景的“工具类”,不是 ToUpper 那种辅助函数
如果你在模板里频繁写 {{with $f := field "user.Name" .}}{{end}},说明你已经踩进 Revel 的核心抽象层了。field 不是普通工具函数,它自动绑定校验状态、当前值、HTML 属性和错误类名,省掉手动传参、判空、拼属性的全部逻辑。
-
field必须配合控制器里的c.Validation.Error("user.Name")才生效,否则$f.Error永远为空字符串 - 下拉菜单用
{{option $f "admin" "管理员"}},单选用{{radio $f "M"}},它们会自动加selected或checked - 字段路径支持嵌套,如
"profile.Address.City",但结构体字段必须导出(首字母大写)
真要注册自定义函数,必须在 app/init.go 的 init() 里注册,且只认导出函数
想加 FormatTime 或 Truncate 这类函数?必须在 app/init.go 的 init() 函数里调用 revel.TemplateFuncs["formatTime"] = FormatTime,然后重启服务——改完不重启,模板里永远报 function "formatTime" not defined。
关键约束有三个:
- 函数名必须首字母大写,
func FormatTime(t time.Time, layout string) string✅,func formatTime(...)❌(静默忽略) - 参数类型必须严格匹配,
.CreatedAt是string却传给期望time.Time的函数,会 panic - 不能在
template.ParseFiles之后再补注册,函数映射是在 parse 阶段固化进 AST 的,运行时加无效
模板里调用 revel.Message 就是多语言“工具函数”,不用自己封装
国际化不是靠写 Translate(key, args) 实现的,而是直接用 Revel 自带的 {{ revel.Message "login.success" .User }} 或更简洁的 {{ T "login.success" .User }}(前提是控制器里已设 c.RenderArgs["T"] = c.Message)。
容易被忽略的点:
- 消息文件必须放在
/messages目录下,命名如auth.en,后缀只能是en、zh这种短码,en-US不识别 -
revel.Message第二个参数是可选的interface{},传结构体时字段名要跟消息里占位符一致,比如hello.name={{.Name}},就得传&User{Name:"Alice"} - 如果没启用
revel.I18nFilter,或它没放在ParamsFilter之后,所有Message调用都返回原始 key,不报错也不提示
最常被绕过的其实是 field 和 revel.Message ——它们不是“辅助工具”,而是 Revel 对表单和 i18n 的领域建模结果。硬要用自定义函数重实现,反而丢掉上下文感知和错误联动能力。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











