Goのhtml/template
パッケージは、HTMLテンプレートのための豊富なテンプレート言語を提供します。これは主にWebアプリケーションで、クライアントのブラウザに構造化された方法でデータを表示するために使用されます。Goのテンプレート言語の大きな利点の1つは、データの自動エスケープです。GoはHTMLテンプレートを解析し、ブラウザに表示する前にすべての入力をエスケープするため、XSS攻撃を心配する必要はありません。
Goでテンプレートを作成するのは非常に簡単です。この例では、HTMLの順序なしリスト(ul)として記述されたTODOリストを示します。テンプレートをレンダリングするとき、渡されるデータはGoのデータ構造であればどのような種類でもかまいません。単純な文字列または数値でも、以下の例のようにネストされたデータ構造でもかまいません。テンプレート内のデータにアクセスするには、最上位の変数は{{.}}
でアクセスします。中括弧内のドットはパイプラインと呼ばれ、データのルート要素です。
data := TodoPageData{
PageTitle: "My TODO list",
Todos: []Todo{
{Title: "Task 1", Done: false},
{Title: "Task 2", Done: true},
{Title: "Task 3", Done: true},
},
}
<h1>{{.PageTitle}}</h1>
<ul>
{{range .Todos}}
{{if .Done}}
<li class="done">{{.Title}}</li>
{{else}}
<li>{{.Title}}</li>
{{end}}
{{end}}
</ul>
テンプレート言語には、HTMLをレンダリングするための豊富な制御構造のセットが含まれています。ここでは、最も一般的に使用されるものの概要を説明します。可能なすべての構造の詳細なリストについては、text/templateを参照してください。
制御構造 | 定義 |
---|---|
{{/* コメント */}} |
コメントを定義します |
{{.}} |
{{.}} |
ルート要素をレンダリングします |
{{.Title}} |
ネストされた要素の「Title」フィールドをレンダリングします |
{{if .Done}} {{else}} {{end}} |
if文を定義します |
{{range .Todos}} {{.}} {{end}} |
すべての「Todos」をループし、 |
{{block "content" .}} {{end}} |
ファイルからのテンプレートの解析
tmpl, err := template.ParseFiles("layout.html")
// or
tmpl := template.Must(template.ParseFiles("layout.html"))
layout.html
というテンプレートファイルがあります。リクエストハンドラーでのテンプレートの実行
func(w http.ResponseWriter, r *http.Request) {
tmpl.Execute(w, "data goes here")
}
Execute
関数は、テンプレートを書き出すためのio.Writer
と、テンプレートにデータを渡すためのinterface{}
を受け入れます。関数がhttp.ResponseWriter
で呼び出されると、Content-TypeヘッダーはHTTPレスポンスで自動的にContent-Type: text/html; charset=utf-8
に設定されます。コード(コピー/ペースト用)
package main
import (
"html/template"
"net/http"
)
type Todo struct {
Title string
Done bool
}
type TodoPageData struct {
PageTitle string
Todos []Todo
}
func main() {
tmpl := template.Must(template.ParseFiles("layout.html"))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
data := TodoPageData{
PageTitle: "My TODO list",
Todos: []Todo{
{Title: "Task 1", Done: false},
{Title: "Task 2", Done: true},
{Title: "Task 3", Done: true},
},
}
tmpl.Execute(w, data)
})
http.ListenAndServe(":80", nil)
}
<h1>{{.PageTitle}}</h1>
<ul>
{{range .Todos}}
{{if .Done}}
<li class="done">{{.Title}}</li>
{{else}}
<li>{{.Title}}</li>
{{end}}
{{end}}
</ul>