Go 視圖模板篇(五):模板布局和繼承
模板布局與繼承
在 Go 模板中,可以結(jié)合 define 指令和 template 指令實現(xiàn)模板布局功能。
首先編寫一段服務(wù)端示例代碼:
package?main
import?(
????"html/template"
????"net/http"
)
func?layoutExample(w?http.ResponseWriter,?r?*http.Request)??{
????t?:=?template.Must(template.ParseFiles("layout.html"))
????t.ExecuteTemplate(w,?"layout",?"")
}
func?main()??{
????http.HandleFunc("/layout",?layoutExample)
????http.ListenAndServe(":8080",?nil)
}
對應(yīng)的模板文件 layout.html 代碼如下,這里我們將子視圖模板和布局模板寫到一個文件:
{{?define?"layout"?}}
<html?lang="en">
<head>
????<meta?charset="UTF-8">
????<title>Layouttitle>
head>
<body>
????{{?template?"content"?.?}}
body>
html>
{{?end?}}
{{?define?"content"?}}
????Hello?World!
{{?end?}}
運行服務(wù)端代碼,在終端窗口通過 curl 訪問 /layout 路由,返回結(jié)果如下:

當(dāng)然我們也可以在另一個模板文件中定義 content 子模板,比如 hello.html:
{{?define?"content"?}}
????Hello?World!
{{?end?}}
然后在 layout.html 中移除 content 的定義,在處理器中增加對 hello.html 的解析:
t?:=?template.Must(template.ParseFiles("layout.html",?"hello.html"))
t.ExecuteTemplate(w,?"layout",?"")
結(jié)果完全一樣。
可以看到,通過 define 指令,我們才可以真正實現(xiàn)布局文件的復(fù)用,之前那種按照文件名作為模板名的方式在這里顯然不適用,因為這樣一來,布局文件只能被一個子模板使用。
我們還可以實現(xiàn)一些更高級的玩法:
func?layoutExample(w?http.ResponseWriter,?r?*http.Request)??{
????rand.Seed(time.Now().Unix())
????var?t?*template.Template
????if?rand.Intn(10)?>?5?{
????????t?=?template.Must(template.ParseFiles("layout.html",?"hello_blue.html"))
????}?else?{
????????t?=?template.Must(template.ParseFiles("layout.html",?"hello_red.html"))
????}
????t.ExecuteTemplate(w,?"layout",?"")
}
新增模板文件 hello_blue.html:
{{?define?"content"?}}
????"color:?blue;">Hello?World!h1>
{{?end?}}?
和 hello_red.html:
{{?define?"content"?}}
????"color:?red;">Hello?World!h1>
{{?end?}}???
再次運行服務(wù)端代碼,在瀏覽器訪問 /layout 路由,就可以隨機(jī)看到紅色和藍(lán)色文本了(概率各 50%):


使用區(qū)塊指令定義默認(rèn)模板
我們可以通過 block 指令定義默認(rèn)區(qū)塊模板:
{{?block?arg?}}?
????Dot?is?set?to?arg?
{{?end?}}
修改上述 layout.html 代碼如下:
{{?define?"layout"?}}
<html?lang="en">
<head>
????<meta?charset="UTF-8">
????<title>Layouttitle>
head>
<body>
????{{?block?"content"?.?}}
????????<h1?style="color:?red;">Hello?World!h1>
????{{?end?}}
body>
html>
{{?end?}}
然后調(diào)整處理器代碼:
func?layoutExample(w?http.ResponseWriter,?r?*http.Request)??{
????rand.Seed(time.Now().Unix())
????var?t?*template.Template
????if?rand.Intn(10)?>?5?{
????????t?=?template.Must(template.ParseFiles("layout.html",?"hello_blue.html"))
????}?else?{
????????t?=?template.Must(template.ParseFiles("layout.html"))
????}
????t.ExecuteTemplate(w,?"layout",?"")
}
在 else 區(qū)塊沒有指定 content 模板,此時由于布局模板中使用 block 指令定義了默認(rèn)區(qū)塊內(nèi)容,所以也能實現(xiàn)同樣的效果。
(全文完)
推薦閱讀
站長 polarisxu
自己的原創(chuàng)文章
不限于 Go 技術(shù)
職場和創(chuàng)業(yè)經(jīng)驗
Go語言中文網(wǎng)
每天為你
分享 Go 知識
Go愛好者值得關(guān)注
