前段時間,在項目開發中經常和go語言的HTMLL template打交道,特意總結了幾點我在使用中經常遇到不太明確的,比較糾結疑惑的知識點,鞏固一下,也方便以後查找。
至於關於go template的系統性的介紹說明,這是一篇我經常查看的文章,寫的非常全面。
1、作用域訪問
go template中最常打交道的就是點作用域,點"."代表當前作用域的當前對象,因此在通常情況下,”.“指的就是傳給template的Execute方法的數據對象。這裏針對是在在Gin環境中,數據對象就是傳遞給*gin.Context的HTML方法的第三個參數
dataContext := gin.H{"examID":exam_id, "examName": exam.Name, "questions": qtypeQuestionsMap}
c.HTML(200, "ffe/exams.tmpl", dataContext)
對應與上面的template執行代碼,在模板中的頂級作用域就是上面的dataContext對象,那麼”{{ .questions}}”獲得的就是dataContext["questions"]
對於在range、with方法中,"."相應的變爲當前迭代的項目或with的對象,此時如果要訪問頂級作用域中的屬性,就要用到"$"這個一直指向模板級頂級作用域的特殊符號了,注意是模板級的,在子模板中"$"並不能指向父模板的數據對象(當然可以傳遞過去)
{{ range $qtype,$qss:=.questions }}
{{ $ind = inc $ind }}
{{/*在range中訪問頂級作用域中的對象qtypeMap並調用index方法,同時聲明瞭$qts局部變量可以在後續代碼中使用*/}}
{{ $qts := index $.qtypeMap $qtype }}
<div class="qtype" data-qtype="{{$qts.QtypeID}}">{{$qts.QtypeName}}</div>
{{ end }}
2、方法調用
GO template中調用實例方法很簡單,和訪問實例的字段屬性一樣,不要使用call函數,直接dot+方法名就行了,但是這裏有幾點要注意:
-
方法只能返回一個值,或者第二個返回值是Error類型
-
Template執行時,調用方法的主體區分是否指針,不會自動裝換,這點需要特別注意
-
方法有參數不需要括號,直接依次空格分割傳遞就行了,例如下面的ItemScore方法需要2個int參數
{{ $qts.ItemScore 2 2}}
-
方法的連續調用,需要用管道符”|“來鏈接,比如下面的示例,需要調用”.q“的”QOHtmlTyped“方法,參數爲” false“,然後在調用自定義模板方法”html“
{{ .q.QOHtmlTyped false | html }}
3、自定義函數
funcMap:=template.FuncMap{
"html": func(s string) template.HTML{
return template.HTML(s)
},
"inc": func(n int)int{
return n+1
},
"avg": func(total float64, count float64)float64{
return total/ count
},
"avgByInt": func(total float64, count int)float64{
return total/ float64(count)
},
"add": func(n int,an ...int)int{
s:=n
for _,a:=range an{
s += a
}
return s
},
}
上面代碼是我自定義的一些常用方法,雖然很簡單,但是在模板中不能實現,只能通過自定義函數來實現。
對於Gin環境下,只需要調用 *gin.Engine的”SetFuncMap“方法就可以了。
由於我使用了第三方multitemplate庫,需要調用multitemplate Render的方法
render := multitemplate.NewRenderer()
...
render.AddFromFilesFuncs(name,funcMap,files...)