Revel模板不能校验数据,因它是纯渲染层,无执行能力;所有校验必须在控制器中通过c.Validation链式方法完成,模板仅安全读取已写入的.errors和.flash数据。

Revel 模板里不校验数据,校验必须在控制器(Controller)里做;模板只负责读取校验结果并安全渲染——漏掉 c.Validation.Keep() 或 c.FlashParams(),用户就看不到任何错误提示。
为什么模板里不能写校验逻辑
Revel 的模板是纯渲染层,没有执行校验的能力。所有 .errors.username.Message 这类访问,背后依赖的是控制器中 c.Validation 上下文写入的数据。如果控制器没调用 Required()、MinSize() 等方法,.errors 就是空 map,模板里 {{if .errors.username}} 永远为 false。
- 模板函数如
field、option也只读取已存在的.errors和.flash,不触发新校验 - 试图在模板里用
eq或自定义函数做“格式判断”,属于前端补救,无法替代服务端校验 - 结构体上的
valid:"required"标签只在revel.InterceptFunc拦截器启用时生效,且仅作用于绑定到结构体字段的参数,不作用于裸字符串参数
表单提交后错误不显示?检查这三步
这是最常卡住开发者的环节:表单提交失败,但页面刷新后啥提示都没有,输入框还清空了。
- 控制器中是否在验证后立即调用了
c.Validation.Keep()?没它,.errors不会写进 Flash cookie,重定向后丢失 - 是否紧接着调用了
c.FlashParams()?没它,.flash.username为空,input 的value="{{.flash.username}}"渲染不出原值 - 重定向目标 Action(比如
Hotels.Settings)是否调用了c.Render()?如果只写return c.Redirect(...)而没在目标方法里Render(),模板根本收不到.errors和.flash
模板里怎么安全显示错误信息
直接写 {{.errors.username.Message}} 很危险——万一 .errors 是 nil,Revel 不报错,而是静默输出空字符串,用户完全感知不到问题。
- 字段级提示必须加判空:
{{if .errors.username}}<small class="text-danger">{{.errors.username.Message}}</small>{{end}} - 顶部聚合提示可用
{{range $key, $err := .errors}}{{$err.Message}}{{end}},但注意:这会丢失字段名,无法定位具体哪个 input 出错 - 想兼顾两者?先顶部汇总,再每个 input 下补一句字段级提示——别省略
{{if .errors.xxx}}判断 -
.flash.username的值来自原始请求参数,不是数据库查出来的;若字段名和参数名不一致(比如表单name="user_name",但控制器接收为username string),.flash.user_name才有效,.flash.username为空
最容易被忽略的是:Revel 的 Match() 正则必须省略末尾 $,写成 ^\w* 而非 ^\w*$;还有 MinSize/MaxSize 按字节计数,中文输入可能被误判超长——这些细节不会在模板里暴露,只能靠控制器日志或单元测试提前发现。


















