Go には標準パッケージとしてテンプレート機能が用意されています。 テンプレート機能は、定型の Web ページ作成などに活用できます。
2つのテンプレートパッケージ
Go 言語には、組込みのテンプレート・パッケージとして、text/template
と html/template
パッケージが搭載されています。
Web ページの構築に使用する場合は、パラメータを HTML エスケープ処理してくれる html/template
パッケージの方を利用します。
テンプレート機能の基本的な使い方
Template オブジェクトの生成
テンプレート機能を使用するには、まずは Template
オブジェクトを生成します。
テンプレートファイルを使用する場合は template.ParseFiles
関数、文字列データをテンプレートとして使用する場合は template.Parse
関数を使用します。
t, err := template.ParseFiles("./template.html")
if err != nil {
log.Fatal(err)
}
テンプレートファイルのパース処理が成功することが分かっている場合は、次のように template.Must
関数を組み合わせて使用することで、エラー処理の記述を省略することができます(エラーになった場合は panic が発生します)。
t := template.Must(template.ParseFiles("./template.html"))
テンプレートへの値の埋め込み
テンプレートへの値の埋め込みは、Template
オブジェクトの Execute
メソッドによって行います。
第一引数には出力先、第二引数には埋め込むデータを渡します。
data := "Hello World"
if err := t.Execute(os.Stdout, data); err != nil {
log.Fatal(err)
}
渡されたデータは、テンプレートファイル内の、{{ . }}
という部分に展開されます。
この構文は、Hugo という静的サイトジェネレーターを使っている場合はおなじみかもしれません。
下記はシンプルなテンプレートファイルの例です。
全体のコード
テンプレートへの入力データとしてマップや構造体を使用する
Template
オブジェクトの Execute
メソッドには、単純な文字列だけではなく、マップや構造体を渡すこともできます(こちらの方が一般的)。
下記のコードでは、3つのキーを持つマップを渡しています。
data := map[string]int{
"key1": 100,
"key2": 200,
"key3": 300,
}
if err := t.Execute(os.Stdout, data); err != nil {
log.Fatal(err)
}
渡されたデータは、テンプレート内で {{ .キー名 }}
で参照することができます。
<ul>
<li>{{ .key1 }}
<li>{{ .key2 }}
<li>{{ .key3 }}
</ul>
次のサンプルコードでは、構造体のオブジェクトをテンプレートに渡しています。
type Book struct {
Title string
Author string
}
data := Book{Title: "Golang", Author: "Maku"}
if err := t.Execute(os.Stdout, data); err != nil {
log.Fatal(err)
}
テンプレートに渡された構造体の各フィルードの値も、マップの場合と同様な形式でアクセスすることができます。
<ul>
<li>{{ .Title }}
<li>{{ .Author }}
</ul>
構造体のフィールドとして、構造体やマップを持っているようなケースでは、次のようにドットで連鎖させることで参照できます。
<h1>{{ .Site.Title }}</h1>
テンプレート内でのループ処理
range
キーワードを使用すると、テンプレートファイル内でループ処理を行うことができます。
Go 言語のように、インデックスと値を取得しながらループ処理することもできます。
<ul>
{{ range $i, $val := . }}
<ul>{{ $i }} : {{ $val }}
{{ end }}
</ul>
テンプレートの中からテンプレートをインクードする
テンプレートファイルの中で、template
関数を使用すると、別のテンプレートファイルの内容をそこに展開することができます。
入れ子構造で読み込むテンプレートファイルも、template.ParseFiles
関数で指定しておく必要があります。
その他
コメント
テンプレートファイルの中で、{{/*
と */}}
で囲んだ部分はコメントと見なされ、テンプレートのコンパイル時に削除されます。
{{/* これはコメント */}}
前後の空白を削除
テンプレート内で値を出力するときに、{{-
と -}}
で囲むようにすると、前後のスペース(前のタグからそこまでと、そこから後ろのタグまでのスペース)を削除して出力することができます。
前方のスペースのみ、あるいは、後方のスペースのみを削除することもできます。