Go 視圖模板篇(二):模板指令
指令用于在 Go 模板中嵌入命令,通過 {{ 和 }} 來定義,Go 提供了豐富的指令集,包括條件判斷、循環(huán)、設(shè)置和引入等。
在眾多 Go 模板指令中,. 是最重要的一個,它用于解析傳遞到模板的數(shù)據(jù),其他指令和函數(shù)大多都是圍繞這個 . 進(jìn)行格式化和顯示。
1、條件指令
要在視圖模板中使用 if 條件判斷,可以這么做:
{{?if?arg?}}?
????some?content?
{{?end?}}
還可以編寫 if…else… 控制結(jié)構(gòu)語句:
{{?if?arg?}}?
????some?content?
{{?else?}}
????other?content?
{{?end?}}
其中 arg 可以是常量、變量、或者返回某個值的函數(shù)或方法。
下面看一個簡單的示例,編寫服務(wù)端處理器代碼如下:
package?main
import?(
????"html/template"
????"math/rand"
????"net/http"
????"time"
)
func?process(w?http.ResponseWriter,?r?*http.Request)??{
????t?:=?template.Must(template.ParseFiles("condition.html"))
????rand.Seed(time.Now().Unix())
????t.Execute(w,?rand.Intn(10)?>?5)
}
func?main()??{
????http.HandleFunc("/condition",?process)
????http.ListenAndServe(":8080",?nil)
}
對應(yīng)的模板代碼 condition.html:
<html?lang="en">
<head>
????<meta?charset="UTF-8">
????<title>Condition?Actionstitle>
head>
<body>
????{{?if?.?}}
????????Number?is?greater?than?5!
????{{?else?}}
????????Number?is?less?than?or?equal?to?5!
????{{?end?}}
body>
html>
運行服務(wù)端代碼啟動服務(wù)器,在終端窗口通過 curl 請求 /condition 路由,可以看到對應(yīng)的返回結(jié)果如下:

2、迭代指令
迭代指令可以用于循環(huán)迭代數(shù)組、切片、字典和通道:
{{?range?array?}}?
????Dot?is?set?to?the?element?{{?.?}}?
{{?end?}}
編寫一段服務(wù)端處理器示例代碼如下:
package?main
import?(
????"html/template"
????"net/http"
)
func?iterationActionExample(?w?http.ResponseWriter,?r?*http.Request)??{
????t?:=?template.Must(template.ParseFiles("iteration.html"))
????daysOfWeek?:=?[]string{"Mon",?"Tue",?"Wed",?"Thu",?"Fri",?"Sat",?"Sun"}
????t.Execute(w,?daysOfWeek)
}
func?main()?{
????http.HandleFunc("/iteration",?iterationActionExample)
????http.ListenAndServe(":8080",?nil)
}
以及對應(yīng)的模板代碼 iteration.html:
<html?lang="en">
<head>
????<meta?charset="UTF-8">
????<title>Iteration?Actionstitle>
head>
<body>
????<ul>
????????{{?range?.?}}
????????????<li>{{?.?}}li>
????????{{?end?}}
????ul>
body>
html>
運行服務(wù)端代碼啟動服務(wù)器,在瀏覽器訪問 http://localhost:8080/iteration,輸出結(jié)果如下:

可以看到無論是外層的循環(huán)體,還是循環(huán)體內(nèi)部的元素,都是通過 . 來替代。如果待迭代的變量為空的話,還可以通過下面這種方式來處理:
<ul>
????{{?range?.?}}
????????<li>{{?.?}}li>
????{{?else?}}
????????<p>Nothing?to?showp>
????{{?end?}}
ul>
3、設(shè)置指令
此外,在 Go 模板中,還可以通過 with 指令設(shè)置變量值:
{{?with?arg?}}?
????Dot?is?set?to?arg?
{{?end?}}
這樣一來,在 {{ with arg }} 和 {{ end }} 之間的 . 會被設(shè)置為 arg。
我們編寫一段示例代碼進(jìn)行演示,對應(yīng)的服務(wù)端處理器代碼如下:
package?main
import?(
????"html/template"
????"net/http"
)
func?setActionExample(w?http.ResponseWriter,?r?*http.Request)??{
????t?:=?template.Must(template.ParseFiles("set.html"))
????t.Execute(w,?"golang")
}
func?main()??{
????http.HandleFunc("/set_action",?setActionExample)
????http.ListenAndServe(":8080",?nil)
}
對應(yīng)的模板文件 set.html 代碼如下:
<html?lang="en">
<head>
????<meta?charset="UTF-8">
????<title>Set?Actiontitle>
head>
<body>
????<div>The?dot?is?{{?.?}}div>
????<div>
????????{{?with?"php"?}}
????????????Now?the?dot?is?set?to?{{?.?}}
????????{{?end?}}
????div>
????<div>The?dot?is?{{?.?}}?againdiv>
body>
html>
運行服務(wù)端代碼啟動服務(wù)器,在瀏覽器中訪問 http://localhost:8080/set_action,返回結(jié)果如下:

同樣,設(shè)置指令也支持 else:
{{?with?arg?}}?
????Dot?is?set?to?arg?
{{?else?}}
????Fallback?if?arg?is?empty?
{{?end?}}
其含義是如果 arg 值為空,則調(diào)用 else 區(qū)塊對應(yīng)的邏輯,例如:
{{?with?""?}}?
????Dot?is?set?to?{{?.?}}?
{{?else?}}
????Dot?is?still?{{?.?}}
{{?end?}}
4、引入指令
最后,我們還可以通過引入指令來嵌入子模板:
{{?template?"name"?}}
我們編寫一段服務(wù)端處理器示例代碼如下,這里我們解析了兩個模板文件,其中 t1.html 是主模板,t2.html 是前者引入的子模板:
package?main
import?(
????"html/template"
????"net/http"
)
func?includeActionExample(w?http.ResponseWriter,?r?*http.Request)??{
????t?:=?template.Must(template.ParseFiles("t1.html",?"t2.html"))
????t.Execute(w,?"Hello?World!")
}
func?main()??{
????http.HandleFunc("/include",?includeActionExample)
????http.ListenAndServe(":8080",?nil)
}
對應(yīng)的模板文件 t1.html 代碼(主模板,通過 template 指令引入子模板 t2.html):
<html?lang="en">
<head>
????<meta?charset="UTF-8">
????<title>Template?1title>
head>
<body>
????<div>?This?is?t1.html?before?div>
????<div>?This?is?the?value?of?the?dot?in?t1.html?-?[{{?.?}}]?div>
????<hr/>
????{{?template?"t2.html"?}}
????<hr/>
????<div>?This?is?t1.html?after?div>
body>
html>
以及模板文本 t2.html 代碼(這是一個子模板):
<div?style="background-color:?yellow;">
????This?is?t2.html
????<br/>
????This?is?the?value?of?the?dot?in?t2.html?-?[{{?.?}}]
div>
運行服務(wù)端代碼啟動服務(wù)器,在瀏覽器中訪問 http://localhost:8080/include,輸出結(jié)果如下:

可以看到嵌套模板中的變量值為空,這是因為我們沒有從第一個模板將變量傳入第二個模板,如果要傳入的話可以這么做:
{{?template?"t2.html"?.?}}
這樣就可以在嵌套模板中看到這個值了:

(全文完)
推薦閱讀
站長 polarisxu
自己的原創(chuàng)文章
不限于 Go 技術(shù)
職場和創(chuàng)業(yè)經(jīng)驗
Go語言中文網(wǎng)
每天為你
分享 Go 知識
Go愛好者值得關(guān)注
