Go的html/template不支持&&、||,须用and、or等内置函数;多条件需括号分组;空值要先判非nil;复杂逻辑应移至handler层处理。

模板里不能直接写 if a && b,得用 and 函数
Go 的 html/template 不支持原生的 &&、|| 运算符,所有逻辑组合必须通过内置函数完成。比如想判断用户既是管理员又已激活,不能写 {{if .Role == "admin" && .Active}},会报错:unexpected boolean operator &&。
正确写法是把条件拆成独立表达式,再用 and 连接:
{{if and (eq .Role "admin") .Active}}
<p>欢迎管理员</p>
{{end}}
-
eq是比较函数,等价于==;还有ne(不等于)、gt(大于)等 -
.Active本身是布尔字段,可直接作为参数传入and,不用加括号 -
and支持多个参数:and .A .B .C相当于 A ∧ B ∧ C
or 和嵌套 and/or 的写法容易漏掉括号
多条件混合时,括号层级决定执行顺序。比如“是管理员或(是编辑且已审核)”,必须显式分组:
{{if or (eq .Role "admin") (and (eq .Role "editor") .Reviewed)}}
<p>有编辑权限</p>
{{end}}
如果写成 or (eq .Role "admin") (eq .Role "editor") .Reviewed,.Reviewed 会被当成第三个独立参数,or 就变成三元运算,语义就变了。
-
or同样支持多参数:or .A .B .C表示任意一个为真即成立 - 嵌套时,每个子表达式必须用括号包裹,否则解析器无法识别边界
- 复杂逻辑建议先在 handler 中预计算布尔值(如
"CanEdit": true),模板里只做单层判断,更易读也更安全
字符串多值匹配要用 in,别硬写一堆 or
判断角色是否属于多个可选值(如 "admin"、"moderator"、"editor"),不要展开成 or (eq .Role "admin") (eq .Role "moderator") ... —— 冗长且难维护。
用 in 函数更简洁:
{{if in .Role "admin" "moderator" "editor"}}
<p>后台操作入口可见</p>
{{end}}
-
in第一个参数是待查值,后面全是候选值,顺序无关 - 注意:它只支持字面量列表,不能传 slice 变量(
in .Role .AllowedRoles会报错) - 若需动态列表,应在 handler 中用
map[string]bool预处理,比如"IsStaff": true,模板里直接用{{if .IsStaff}}
空值和 nil 判断要小心,nil 不能直接参与 and/or
如果 .User 是 nil 指针,{{if and .User .User.Role}} 会 panic:nil pointer dereference。模板不会自动短路。
必须先确保结构体非 nil,再访问字段:
{{if and .User (eq .User.Role "admin")}}
<p>管理员面板</p>
{{end}}
- 单独判
.User是安全的(nil 结构体指针在模板中为 false) - 但
.User.Role在.User为 nil 时不可访问,所以and的第二个参数必须是带保护的表达式 - 更稳妥的做法是在 handler 中统一注入
"CurrentUser": user,并保证user是非 nil 值或空结构体,避免模板里反复防御性判断


















