
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/%7B%7B.ImageUrl%7D%7D" alt="{{.Title}}"><a href="/product"><h3>{{.Title}}</h3></a>
<p>{{.Description}}</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/learn/7564" title="使用Go语言搭建家庭相册系统-相关课件"><img
src="https://img.php.cn/upload/webcode/000/000/164/636a2b4d84031727.png" alt="使用Go语言搭建家庭相册系统-相关课件" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/learn/7564" title="使用Go语言搭建家庭相册系统-相关课件" class="overflowclass">使用Go语言搭建家庭相册系统-相关课件</a>
<p class="overflowclass">使用Go语言搭建家庭相册系统-相关课件</p>
</div>
<a rel="nofollow" href="/xiazai/learn/7564" title="使用Go语言搭建家庭相册系统-相关课件" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<p>{{.Price}} / liter</p>
</div>
{{if mod $index 4}}<div class="row">{{end}}
{{end}}<p>⚠️ 注意事项:</p>
<ul>
<li>$index 从 0 开始计数,因此 mod $index 4 在 index=0,4,8,... 时为 true,适合“每 4 项开启新行”;</li>
<li>若需闭合 </li>
</ul>
</div>,建议搭配 else 或更健壮的逻辑(如使用 mod (add $index 1) 4 判断末尾),或改用 slice + range 分块处理,避免首尾错位;<li>自定义函数必须在 Parse() 前注册,且参数/返回类型需明确(int, bool 等);</li>
<li>函数名应简洁、无歧义;避免与内置函数(如 print, len)重名。</li>
<p>? 进阶提示:对于复杂布局,可扩展函数如 divmod(返回商和余数)或 chunk(按大小切分 slice),进一步提升模板表达力。但始终遵循“模板只负责展示,逻辑尽量前置”的最佳实践——关键业务计算应在 handler 层完成,而非塞入模板。</p>
</div>










