Go使用Text和HTML模板
阿新 • • 發佈:2019-02-05
簡介
Go的兩個包text/template
和html/template
提供了將變數的值替換到文字的機制。通常用在一些printf
應付不了的、需要複雜的格式化的場合。
模板的使用
模板規則
Action
模板是一個包含了一個或多個雙花括號標記({{...}}
)的字串,這種雙花括標記號叫做Action。模板中所有的除Action的字串都按照原樣列印,Action則表現了特殊的行為。通過Action可以列印變數的值、欄位的值、呼叫函式或方法、表達控制流程等。
Dot
Action中的點(.
)表示當前值。初始值為傳遞給模板的引數。
API
text/template與html/template提供了相同的API來建立、解析和執行模板,區別是html/template提供了HTML轉義。
// 建立一個名字為name的模板 func New(name string) *Template // 解析模板字串 func (t *Template) Parse(text string) (*Template, error) // 解析檔案 func ParseFiles(filenames ...string) (*Template, error) // 執行模板,將結果寫入wr func (t *Template) Execute(wr io.Writer, data interface{}) error
在確定模板可以正確解析的場合,可以使用Must()來處理Parse()的結果。如果Parse()失敗,則呼叫panic(),如果成功,返回Template物件。
func Must(t *Template, err error) *Template
Funcs()用來註冊函式給模板,註冊之後模板就可以通過名字呼叫外部函數了(見下面例子)。
func (t *Template) Funcs(funcMap FuncMap) *Template type FuncMap map[string]interface{}
輸入
例子
最基本的使用
package main
import (
"log"
"os"
"text/template" // 引入包,如果處理HTML,則為 "html/template"
)
func main() {
// 建立一個名字為report的模板,並解析一個字串
t, err := template.New("report").Parse("I am {{.}} years old.")
if err != nil {
log.Fatal(err)
}
// 執行模板,5作為引數傳遞,將結果寫到標準輸出
t.Execute(os.Stdout, 5)
// 列印結果:I am 5 years old.
}
訪問複合資料結構的值
訪問結構體欄位需要在點(.
)後面加欄位名。
訪問Map值需要在點(.
)後面加Key的值。
package main
import (
"os"
"text/template"
)
func main() {
t := template.Must(
template.New("report").Parse("I am {{.Age}} years old.\n"))
t.Execute(os.Stdout, struct{ Age int }{5})
t.Execute(os.Stdout, map[string]int{"Age": 5})
}
需要注意的是template訪問結構體欄位時利用了反射機制,因此必須匯出欄位才能在模板裡訪問。
迴圈
使用{{range}}
和{{end}}
來表示迴圈。每次迭代中點(.
)代表當前迭代的值。
package main
import (
"os"
"text/template"
)
func main() {
const temStr = "{{range .}}{{.}}\n{{end}}"
t := template.Must(template.New("report").Parse(temStr))
t.Execute(os.Stdout, []string{"Hello", "Gopher"})
}
管道
用|
將其左邊的輸出作為其右邊的輸入。
package main
import (
"os"
"text/template"
)
func main() {
const temStr = `{{. | printf "% 10s"}}`
t := template.Must(template.New("report").Parse(temStr))
t.Execute(os.Stdout, "Gopher")
}
呼叫函式
如果在模板中需要呼叫函式,則在Parse()之前需要通過Funcs()來註冊。
package main
import (
"os"
"text/template"
)
func greet(name string) string {
return "Hello, " + name + "!"
}
func main() {
const temStr = `{{. | greet}}`
t := template.Must(template.New("report").
Funcs(template.FuncMap{"greet": greet}).
Parse(temStr))
t.Execute(os.Stdout, "Gopher")
}
生成動態HTML
HTML檔案:time.html
<html> <body> <p>Current time is: {{.}}</p> </body> </html>
go檔案:
package main import ( "html/template" "log" "net/http" "time" ) func main() { http.HandleFunc("/time", timeHandler) log.Fatal(http.ListenAndServe(":9090", nil)) } func timeHandler(w http.ResponseWriter, r *http.Request) { t := template.Must(template.ParseFiles("time.html")) t.Execute(w, time.Now().Format("2006-01-02 15:04:05")) }