推荐在模板中用{{if gt .score 90}}text-green{{else if gt .score 60}}text-yellow{{else}}text-red{{end}}直接控制class,或注册scoreclass等自定义函数返回预定义class名,避免拼接、内联style及不安全的用户输入处理。

模板中直接用 if 判断数值并切换 class 最简单
Go 的 html/template 不支持内联表达式(比如 {{ .Score > 90 ? "high" : "low" }}),但原生 if、else if、else 完全够用,且语义清晰。关键不是“怎么算”,而是“怎么把判断结果映射到样式上”。
常见错误是试图在模板里写逻辑函数或拼接 class 字符串,这既难维护又容易 XSS(尤其当数值来自用户输入时)。正确做法是:把样式决策提前到 Go 代码层,或在模板内用条件块直接控制 class 属性。
- 推荐在模板里用
{{if gt .Score 90}}text-green{{else if gt .Score 60}}text-yellow{{else}}text-red{{end}} - 避免写
class="{{.ScoreClass}}"并在 handler 中计算ScoreClass—— 这会让模板失去可读性,且一旦逻辑变复杂(比如要叠加多个 class),Go 层容易出错 -
gt、lt、eq是模板内置比较函数,无需额外定义;注意它们只接受两个参数,不支持链式(如60 不合法)
数值区间多时用自定义模板函数更干净
当判断逻辑重复出现(比如评分、状态码、响应延迟毫秒数),硬编码一堆 if 块会让模板臃肿。这时注册一个自定义函数,把样式映射逻辑收口到一处,比分散在多个模板里更可控。
例如注册一个叫 scoreClass 的函数:
func scoreClass(score int) string {
switch {
case score > 90:
return "text-success"
case score > 75:
return "text-warning"
default:
return "text-muted"
}
}
// 注册进 template.FuncMap
t := template.New("page").Funcs(template.FuncMap{
"scoreClass": scoreClass,
})
模板中就变成简洁的:<span class="{{scoreClass .Score}}">{{.Score}}</span>。注意:该函数必须接收明确类型(如 int),不能用 interface{},否则模板执行时会 panic。
- 函数名必须是导出的(首字母大写),否则模板无法识别
- 不要在函数里做 HTTP 请求、DB 查询等耗时操作——模板渲染是同步阻塞的,会拖慢整个响应
- 如果数值可能为 nil(比如
*int),函数需先判空,否则运行时报invalid memory address
CSS 类名必须预定义,别依赖 JS 动态加
有人想在模板里输出内联 style(如 style="color: {{scoreColor .Score}};"),这是反模式。不仅破坏样式与结构分离,还让浏览器无法复用 CSS 规则,影响渲染性能。
真正该做的是:用 class 控制样式,在外部 CSS 文件中统一定义视觉表现。比如:
.text-success { color: #28a745; font-weight: bold; }
.text-warning { color: #ffc107; }
.text-muted { color: #6c757d; opacity: 0.8; }
这样改颜色、加动画、适配暗色模式都只需动 CSS,不用碰 Go 或 HTML 模板。
- 避免使用
!important强覆盖,它会让后续维护变得不可预测 - 如果项目用 Tailwind,可以直接用它的工具类(如
text-emerald-600),但依然建议封装成函数返回完整 class 字符串,而不是在模板里拼接 - 注意 class 名冲突:如果你的模板被嵌入其他页面,确保 class 名有业务前缀(如
report-score-high),避免意外覆盖全局样式
注意模板自动转义对 class 的影响
html/template 默认会对所有插入内容做 HTML 转义,这对 class 属性是安全的(因为 class 值只含字母、短横线、数字),但如果你的 class 名来自不可信输入(比如 URL 参数解析出的 tag),就可能被转义成无效值(如空格变 )。
更隐蔽的问题是:当你用自定义函数返回带空格的 class 列表(如 "text-red font-bold"),必须确保函数返回的是 template.HTML 类型,否则空格会被转义成 ,导致 class 失效。
- 正确写法:
return template.HTML("text-red font-bold") - 错误写法:
return "text-red font-bold"(会被转义为text-red font-bold) - 仅当 class 内容完全可控(如硬编码或枚举值)时才用
template.HTML;若含用户输入,必须先白名单过滤,再转义
最稳妥的方式,还是让 Go 层只返回单一 class 名,把组合逻辑交给 CSS(用 BEM 或 utility-first 方案),避开字符串拼接和转义陷阱。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











