
Go 模板原生不支持 % 运算符,需通过自定义函数(如 mod)在模板中实现取模逻辑,再结合 if 条件判断完成布局分组等需求。
go 模板原生不支持 `%` 运算符,需通过自定义函数(如 `mod`)在模板中实现取模逻辑,再结合 `if` 条件判断完成布局分组等需求。
在 Go 的 text/template 或 html/template 中,模板语法是 deliberately 简化的——它不支持算术运算符(如 +, -, *, /, %),也不允许在模板内直接调用 Go 内置运算。因此,像 {{ $index % 4 == 0 }} 这样的写法会触发 unexpected "%" in operand 错误。
✅ 正确做法是:注册一个自定义模板函数,将取模逻辑封装为可复用的布尔判断工具。例如,定义 mod(i, j int) bool 函数,用于判断索引是否能被某数整除(常用于栅格布局、每行渲染 N 项等场景):
// Go 代码:注册 mod 函数
t := template.Must(template.New("products").Funcs(template.FuncMap{
"mod": func(i, j int) bool { return i%j == 0 },
}))随后,在 HTML 模板中即可安全使用:
{{range $index, $element := .Products}}
{{if mod $index 4}}<div class="row">{{end}}
<div class="columns small-3 product">
<img src="/img/{{.ImageUrl}}" alt="{{.Title}}" />
<a href="/product"><h3>{{.Title}}</h3></a>
<p>{{.Description}}</p>
<p>{{.Price}} / liter</p>
</div>
{{if mod $index 4}}<div class="row">{{end}}
{{end}}⚠️ 注意事项:
- $index 从 0 开始计数,因此 mod $index 4 在 index=0,4,8,... 时为 true,适合“每 4 项开启新行”;
- 若需闭合 </div>,建议搭配 else 或更健壮的逻辑(如使用 mod (add $index 1) 4 判断末尾),或改用 slice + range 分块处理,避免首尾错位;
- 自定义函数必须在 Parse() 前注册,且参数/返回类型需明确(int, bool 等);
- 函数名应简洁、无歧义;避免与内置函数(如 print, len)重名。
? 进阶提示:对于复杂布局,可扩展函数如 divmod(返回商和余数)或 chunk(按大小切分 slice),进一步提升模板表达力。但始终遵循“模板只负责展示,逻辑尽量前置”的最佳实践——关键业务计算应在 handler 层完成,而非塞入模板。


















