Go 視圖模板篇(三):參數(shù)、管道和函數(shù)調(diào)用
參數(shù)
參數(shù)可以看做模板中的變量,參數(shù)值可以是布爾值、整型、字符串、還可以是結(jié)構(gòu)體、結(jié)構(gòu)體的字段、或者數(shù)組的索引。
我們可以這樣設(shè)置參數(shù)值:
$variable?:=?value
乍看起來(lái)沒(méi)啥用,用在指令中則可以大放異彩:
{{?range?$key,?$value?:=?.?}}?
????The?key?is?{{?$key?}}?and?the?value?is?{{?$value?}}?
{{?end?}}
管道
管道是鏈接起來(lái)的參數(shù)、函數(shù)或者方法序列,和 Unix 管道一樣:
{{?p1?|?p2?|?p3?}}
管道允許我們將上一個(gè)輸出作為參數(shù)傳遞到下一個(gè),不同元素之間通過(guò) | 分隔。
服務(wù)端處理器示例代碼:
package?main
import?(
????"html/template"
????"net/http"
)
func?pipelineExample(w?http.ResponseWriter,?r?*http.Request)??{
????t?:=?template.Must(template.ParseFiles("pipeline.html"))
????t.Execute(w,?12.3456)
}
func?main()??{
????http.HandleFunc("/pipeline",?pipelineExample)
????http.ListenAndServe(":8080",?nil)
}
對(duì)應(yīng)的模板文件 pipeline.html 代碼:
<html?lang="en">
<head>
????<meta?charset="UTF-8">
????<title>Pipeline?Demotitle>
head>
<body>
????{{?.?|?printf?"%.2f"?}}
body>
html>
上述管道代碼會(huì)將傳入視圖模板的變量作為 printf 函數(shù)的參數(shù),通過(guò) %.2f 格式打印出來(lái):

printf 函數(shù)封裝了 fmt.Sprintf 方法,是 Go 模板引擎內(nèi)置的函數(shù),如果是自定義函數(shù)的話,需要通過(guò)指定語(yǔ)法將其綁定到模板引擎,否則系統(tǒng)不能識(shí)別,下面我們就來(lái)看看如何在 Go 視圖模板中通過(guò)管道調(diào)用自定義函數(shù)。
自定義函數(shù)
Go 模板引擎內(nèi)置了豐富的基礎(chǔ)函數(shù),其中有很多是 fmt.Sprint 的變體,比如前面示例中使用的 printf。此外,還支持開(kāi)發(fā)者自定義的函數(shù)。
要自定義函數(shù),需要這么做:
創(chuàng)建
FuncMap字典,然后將函數(shù)名作為鍵,將函數(shù)體作為值。將
FuncMap應(yīng)用到模板引擎。
下面我們來(lái)看一個(gè)示例,這個(gè)示例中,我們通過(guò)自定義函數(shù)設(shè)置日期輸出格式。
編寫(xiě)服務(wù)端處理器示例代碼如下:
package?main
import?(
????"html/template"
????"net/http"
????"time"
)
func?formatDate(t?time.Time)?string?{
????layout?:=?"2006-01-02?15:04:05"
????return?t.Format(layout)
}
func?customFunctionExample(w?http.ResponseWriter,?r?*http.Request)??{
????funcMap?:=?template.FuncMap{
????????"fdate":?formatDate,
????}
????t?:=?template.New("function.html").Funcs(funcMap)
????t,?_?=?t.ParseFiles("function.html")
????t.Execute(w,?time.Now())
}
func?main()??{
????http.HandleFunc("/date_format",?customFunctionExample)
????http.ListenAndServe(":8080",?nil)
}
可以看到,我們通過(guò)模板引擎提供的 FuncMap 方法將自定義的 formatDate 函數(shù)注冊(cè)到 fdate 鍵,然后將返回的 funcMap 通過(guò) Funcs 方法注入到視圖模板中,這樣,在對(duì)應(yīng)的視圖模板中就可以調(diào)用 funcMap 中注冊(cè)的自定義函數(shù)了。
對(duì)應(yīng)的模板文件 function.html 代碼如下,我們?cè)诶锩嫱ㄟ^(guò)管道的方式調(diào)用了 fdate 函數(shù):
<html?lang="en">
<head>
????<meta?charset="UTF-8">
????<title>Custom?Functiontitle>
head>
<body>
????<div>?The?date/time?is?{{?.?|?fdate?}}?div>
body>
html>
這里需要注意的是,我們必須在解析模板之前應(yīng)用自定義函數(shù)到模板引擎(前后順序不能顛倒):
t?:=?template.New("function.html").Funcs(funcMap)
t,?_?=?t.ParseFiles("function.html")
這是因?yàn)樵诮馕瞿0鍟r(shí)需要確定模板中使用的函數(shù)。另外,當(dāng)我們通過(guò) New 方法創(chuàng)建模板時(shí),需要手動(dòng)設(shè)置模板名(之前都是自動(dòng)將文件名作為模板名),然后在模板上調(diào)用 ParseFiles 時(shí)再次傳遞的實(shí)際上是待解析的模板文件,而不是模板名,這里需要區(qū)分下。
運(yùn)行服務(wù)端代碼啟動(dòng)服務(wù)器,在瀏覽器中訪問(wèn) http://localhost:8080/date_format,輸出結(jié)果如下,表明自定義日期格式函數(shù)調(diào)用成功:

除了管道之外,還可以在指令中使用自定義的函數(shù),這個(gè)時(shí)候可以將 . 作為參數(shù)傳遞過(guò)來(lái):
<html>?
????<head>?
????????<meta?http-equiv="Content-Type"?content="text/html;?charset=utf-8">?
????????<title>Go?Web?Programmingtitle>?
????head>?
????<body>?
????????<div>The?date/time?is?{{?fdate?.?}}div>?
????body>?
html>
兩種方式實(shí)現(xiàn)的效果一樣,但可以看出,管道的方式更加直觀和靈活,我們還可以在后面繼續(xù)追加其他函數(shù)對(duì)結(jié)果進(jìn)行處理(鏈?zhǔn)秸{(diào)用)。
(全文完)
推薦閱讀
站長(zhǎng) polarisxu
自己的原創(chuàng)文章
不限于 Go 技術(shù)
職場(chǎng)和創(chuàng)業(yè)經(jīng)驗(yàn)
Go語(yǔ)言中文網(wǎng)
每天為你
分享 Go 知識(shí)
Go愛(ài)好者值得關(guān)注
