Go 1.19 HTML模板:如何检测block是否已定义?
解决Go HTML模板中可选Block的渲染问题
要实现未定义description block时不渲染对应的<meta>标签,Go 1.19的模板引擎本身没有内置检测模板是否存在的函数,但可以通过两种简单方式实现:
方法一:通过模板数据传递检测结果
这种方式无需自定义模板函数,直接在渲染前判断模板是否存在,将结果传入模板数据:
1. 修改渲染逻辑
在解析模板后,手动检查description模板是否存在,把结果作为数据字段传入:
package main import ( "html/template" "os" ) func main() { // 解析所有模板文件 tpl, err := template.ParseFiles("layout.gohtml", "content1.gohtml", "content2.gohtml") if err != nil { panic(err) } // 检查是否存在description模板 data := map[string]bool{ "hasDescription": tpl.Lookup("description") != nil, } // 渲染content1(存在description) println("=== 渲染content1 ===") err = tpl.ExecuteTemplate(os.Stdout, "layout", data) if err != nil { panic(err) } // 渲染content2(不存在description) println("\n=== 渲染content2 ===") err = tpl.ExecuteTemplate(os.Stdout, "layout", data) if err != nil { panic(err) } }
2. 更新layout.gohtml模板
用传入的hasDescription字段判断是否渲染meta标签(同时修复你代码中{{end}的语法错误):
<html> <head> <title>{{block "title" .}}The Title{{end}}</title> {{if .hasDescription}} <meta name="description" content="{{template "description" .}}"> {{end}} </head> <body> <header></header> {{template "content" .}} <footer></footer> </body> </html>
方法二:注册自定义模板函数检测模板
如果需要在模板中灵活检测任意模板名称,可以注册一个自定义函数:
1. 注册自定义函数并解析模板
package main import ( "html/template" "os" ) func main() { // 创建模板集并注册hasTemplate函数 tpl := template.New("").Funcs(template.FuncMap{ "hasTemplate": func(name string) bool { return tpl.Lookup(name) != nil }, }) // 解析模板文件 var err error tpl, err = tpl.ParseFiles("layout.gohtml", "content1.gohtml", "content2.gohtml") if err != nil { panic(err) } // 渲染模板 println("=== 渲染content1 ===") err = tpl.ExecuteTemplate(os.Stdout, "layout", nil) if err != nil { panic(err) } println("\n=== 渲染content2 ===") err = tpl.ExecuteTemplate(os.Stdout, "layout", nil) if err != nil { panic(err) } }
2. 更新layout.gohtml模板
直接在模板中调用hasTemplate函数判断:
<html> <head> <title>{{block "title" .}}The Title{{end}}</title> {{if hasTemplate "description"}} <meta name="description" content="{{template "description" .}}"> {{end}} </head> <body> <header></header> {{template "content" .}} <footer></footer> </body> </html>
效果说明
- 渲染
content1.gohtml时,因为定义了descriptionblock,会正常输出<meta name="description" content="An options description"> - 渲染
content2.gohtml时,由于未定义description,meta标签不会被渲染
内容的提问来源于stack exchange,提问作者PrecisionPete
相关产品推荐
相关产品推荐

