Revel模板中布尔字段或非空值直接用{{if .Field}},不可用==或括号;多分支必须{{else if}}连写;比较需用eq/ne等函数;正则匹配须用$name | regexMatch "pattern"管道形式。

模板中直接判断布尔字段或非空值用 {{if .Field}}
Revel 模板底层用的是 Go text/template,所以不能写 {{if .IsAdmin == true}} 或 {{if (.IsAdmin)}} —— 括号、比较运算符都非法。正确写法就是裸写 {{if .IsAdmin}},它会自动对布尔值判真、对切片/map/字符串调用 len()、对指针/接口判非 nil。
常见错误现象:模板编译失败报 unexpected "=" in if,或渲染出空内容(比如 .Items 是 nil 切片却没加检查,{{range .Items}} 直接跳过)。
- 结构体字段如
.IsLoggedIn、.IsActive,直接{{if .IsLoggedIn}} - 切片或 map 是否有内容:
{{if .Users}}足够,不用{{if len .Users}} - 字符串是否非空:
{{if .Title}}等价于{{if ne .Title ""}},更简洁
多分支判断必须用 {{else if}} 且不能换行
Go 模板不支持 elif 或 else if 分开写,{{else}} 和 {{if}} 必须连在一起成 {{else if}},中间不能有空格、换行或注释。
否则会报错 unexpected "if" in else clause,或者只执行第一个 {{if}} 后面的 {{else}} 块,后续分支完全失效。
- 正确:
{{if .Role == "admin"}}...{{else if .Role == "user"}}...{{else}}... - 错误:
{{if ...}}{{else}} {{if ...}}(中间有空格) - 错误:
{{if ...}}\n{{else if ...}}(换行导致解析器断开上下文)
需要比较时必须用 eq/ne/ge 等内置函数
模板里没有 ==、!= 这类操作符,所有比较都得走函数管道。比如判断状态码、角色名、枚举值,必须用 eq、ne、ge 等。
注意 eq 是宽松比较:数字 1 和字符串 "1" 会被认为相等;若需严格类型一致,得在 Controller 层提前转好类型再传入模板。
- 判断字符串:
{{if eq .Status "active"}} - 判断数字:
{{if ge .Age 18}} - 嵌套使用:
{{if and (eq .Type "post") (ne .State "draft")}} - 避免写
{{if .Status == "active"}}(语法错误)
regexMatch 用于正则匹配时管道必须紧贴
如果要用正则做条件判断(比如校验服务名格式、过滤非法路径),Revel 模板本身不带 regexMatch,但 Consul Template 扩展版支持——前提是你的 Revel 项目集成了它,且版本 ≥ 0.19.0。
关键点是:函数必须作为管道末端出现,不能加括号、不能赋值、不能嵌套在 eq 里。写错会导致模板解析失败或永远返回 false。
- 正确:
{{if $name | regexMatch "^[a-z0-9_]+$"}} - 错误:
{{if regexMatch $name "..."}}(参数顺序反了) - 错误:
{{if ($name | regexMatch "...")}}(括号无意义,还可能干扰解析) - 取反要包整个管道:
{{if not ($name | regexMatch "forbidden")}}
容易被忽略的是:模板里的条件逻辑越复杂,越该提前在 Controller 中计算好标志位(如 .CanEdit、.ShowBanner),而不是在模板里堆 and、or 和多层 {{if}} —— 不仅难调试,还会让 View 层悄悄承担业务逻辑。Revel 的约定很明确:View 只负责“怎么画”,不决定“画什么”。











