golangでtemplate(html)の確認
ページを表示する際はテンプレートを使用する
標準では"text/template"と"html/template"が存在する
※他にもあるかもしれないけどあとでやる
参考
Go言語でhttpサーバーを立ち上げてHello Worldをする - Qiita
template - The Go Programming Language
golang で html/template でのテンプレートの継承と、HTML エスケープしないで変数を出力する方法 (Django, Jinja みたいに) - Qiita
[Go言語] templateパッケージでtwigとかのextends的なあれをやるにはどうしようか - Qiita
シンプルなテンプレート
構造
$ tree . ├── main.go └── templates └── index.tpl $
templates/index.tpl
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>golang template test</title> </head> <body> <h1>Golang Template Sample</h1> <p>Title --[{{.Title}}]</p> <p>Message--[{{.Message}}] </p> <div> <h3>Items</h3> {{range .List}} <p>{{.}}</p> {{end}} </div> <div> Link: {{.Link}} </div> </body> </html>
※テンプレートは中括弧("{}")で挟むようです
main.go
package main import ( "fmt" "net/http" "html/template" "time" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now().Format("2006/01/02 15:04:05") + " " + r.URL.Path) // テンプレート用のファイルを読み込む tpl, err1 := template.ParseFiles("templates/index.tpl") if err1 != nil { panic(err1) } // テンプレートを出力 err2 := tpl.Execute(w, struct { Title string Message string List []string Link string }{ Title: "Hello", Message: "World", List: []string{ "Item1", "Item2", "Item3", }, Link: "<a href=\"/\">hoge</a>", }) if err2 != nil { panic(err2) } }) http.ListenAndServe(":9001", nil) }
ページをひらくとこうなる
一部のデータを加工する
templates/index.tpl
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>golang template test</title> </head> <body> <h1>Golang Template Sample</h1> <p>Title --[{{.Title}}]</p> <p>Message--[{{.Message}}] </p> <div> <h3>Items</h3> {{range .List}} <p>{{.}}</p> {{end}} </div> <div> Link: {{.Link | safe}} </div> <div> Link: {{.Link | lock}} </div> </body> </html>
main.go
package main import ( "fmt" "net/http" "html/template" "time" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now().Format("2006/01/02 15:04:05") + " " + r.URL.Path) // 独自関数でエスケープを解除 funcMap := template.FuncMap{ "safe": func(text string) template.HTML { return template.HTML(text) }, "lock": func(text string) string { return "@@[" + text + "]@@" }, } // テンプレート用のファイルを読み込む tpl, _:= template.New("index.tpl").Funcs(funcMap).ParseFiles("templates/index.tpl") // テンプレートを出力 err2 := tpl.Execute(w, struct { Title string Message string List []string Link string }{ Title: "Hello", Message: "World", List: []string{ "Item1", "Item2", "Item3", }, Link: "<a href=\"/\">hoge</a>", }) if err2 != nil { panic(err2) } }) http.ListenAndServe(":9001", nil) }
結果
複数のテンプレートをファイルを使用する
構成
. ├── main.go └── templates ├── base.tpl └── contents.tpl
templates/base.tpl
{{ define "base" }} <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>golang template test</title> </head> <body> <h1>Golang Template Sample</h1> <p>Title --[{{.Title}}]</p> <p>Message--[{{.Message}}] </p> <div> {{ template "contents" . }} </div> </body> </html> {{ end }}
templates/contents.tpl
{{ define "contents" }} <div> <h3>Items</h3> {{range .List}} <p>{{.}}</p> {{end}} </div> <div> Link: {{.Link | safe}} </div> <div> Link: {{.Link | lock}} </div> {{ end }}
main.go
package main import ( "fmt" "net/http" "html/template" "time" ) func main(){ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Println(time.Now().Format("2006/01/02 15:04:05") + " " + r.URL.Path) // 独自関数でエスケープを解除 funcMap := template.FuncMap{ "safe": func(text string) template.HTML { return template.HTML(text) }, "lock": func(text string) string { return "@@[" + text + "]@@" }, } // テンプレート用のファイルを読み込む tpl := template.Must(template.New("hoge").Funcs(funcMap).ParseFiles("templates/base.tpl", "templates/contents.tpl")) // テンプレートを出力 err2 := tpl.ExecuteTemplate(w, "base", struct { Title string Message string List []string Link string }{ Title: "Hello", Message: "World", List: []string{ "Item1", "Item2", "Item3", }, Link: "<a href=\"/\">hoge</a>", }) if err2 != nil { panic(err2) } }) http.ListenAndServe(":9001", nil) }
頭パンクしそう(´・ω・`)
所感
やり方自体はパターンがあるからそのうち理解出来ていくと思うけどgo言語の書き方に慣れていないことや日本語のマニュアルがないのかエラーの意味をうまく理解できていないことがある。
いろいろ参考になりそうなソースがネットで検索したら出てくるので参考にしながらやっていくしかない