Go言語:templateパッケージでHTML等テキストファイルを読み込む(基礎編)
templateパッケージでHTML等の任意のテキストファイルを読み込み、出力する方法を説明する。
なお、APIバージョンGo1で説明する。
バージョン3ではパッケージ名、関数名が異なるので注意。
概要
templateパッケージでは、任意のテキストファイルを読み込み、テキストファイルに埋め込まれたプレースホルダに文字列を変換して出力する。例えば、以下のような機能を利用できる。
- ブラウザからのgetリクエストに対して外部HTMLファイルを読み込み、任意のデータをHTMLに埋め込んでレスポンスとして返す。
- メールの本文テンプレートとして作成したテキストファイルを読み込み、任意のデータを本文に埋め込んでメールを送信する。
例
単にhtmlファイルを読み込んで出力するだけのサンプル
package main
import (
"os"
"fmt"
"text/template"
)
func main() {
var t = template.Must(template.ParseFiles("plainSample.html")) // 外部テンプレートファイルの読み込み
if err := t.Execute(os.Stdout, nil); err != nil { // テンプレート出力
fmt.Println(err.Error())
}
}
plainSample.html
<html>
<head>
<title>Sample Html</title>
</head>
<body>
<h1>Htmlサンプル</h1>
サンプルテキスト
</body>
</html>
出力結果
<html>
<head>
<title>Sample Html</title>
</head>
<body>
<h1>Htmlサンプル</h1>
サンプルテキスト
</body>
</html>
プレースホルダを使用した場合のサンプル
package templatesample
import (
"fmt"
"net/http"
"text/template"
)
type Member struct {
Name string
Message string
}
func init() {
http.HandleFunc("/", handler)
}
func handler(w http.ResponseWriter, r *http.Request) {
member := Member{"inatus", "はじめまして。<br>よろしくお願いいたします。"}
var t = template.Must(template.ParseFiles("placeholderSample.html")) // 外部テンプレートファイルの読み込み
if err := t.Execute(w, member); err != nil { // テンプレート出力
fmt.Println(err.Error())
}
}
placeholderSample.html
<html>
<head>
<title>Sample Html</title>
</head>
<body>
<h1>Htmlサンプル</h1>
<h3>{{.Name}}</h3>
{{.Message}}
</body>
</html>
ブラウザ表示結果
出力をstring型のオブジェクトに格納するサンプル
package main
import (
"fmt"
"bytes"
"text/template"
)
type Member struct {
Name string
Message string
}
func main() {
member := Member{"inatus", "はじめまして。<br>よろしくお願いいたします。"}
var body bytes.Buffer
var t = template.Must(template.ParseFiles("placeholderSample.html")) // 外部テンプレートファイルの読み込み
if err := t.Execute(&body, member); err != nil { // テンプレート出力
fmt.Println(err.Error())
}
var str string = body.String()
}
解説
パッケージ
下記の2種がある。
text/template
: 汎用テンプレート用のパッケージ。html/template
: プレースホルダに変換対象の文字列のhtmlタグをエスケープする。サニタイジングに有効。
インポートするパッケージをhtml/template
に変更して上記の「プレースホルダを使用した場合のサンプル」を実行した結果は以下の通り。
内部的には<
→<
、>
→>
といったように文字列変換される。
テンプレートの読み込み
var t = template.Must(template.ParseFiles("placeholderSample.html"))
template.ParseFiles
関数の引数で渡すパスにあるファイルを読み込む。
パスではなくstringをそのまま引数に渡すこともできる。
var t = template.Must(template.New("html").Parse("<html><body>サンプル</body></html>"))
プレースホルダ変換文字列の指定と出力
if err := t.Execute(w, member); err != nil { // テンプレート出力
fmt.Println(err.Error())
}
上記のテンプレート読み込みの出力変数に対しExecute
関数を実行する。
1つ目の引数には出力先のio.Writer
インタフェイスを指定する。io.Writer
インタフェイスには例えば下記のようなものがある。
http.ResponseWriter
: httpレスポンスへの出力os.Stdout
: 標準出力bytes.Buffer
: 変数への出力
2つ目の引数にはプレースホルダへの変換対象となる文字列を含んだ変数(通常は構造体)を指定する。読み込んだテンプレートのプレースホルダ名({{.Variable}}
)は必ず構造体のメンバ名として存在しなければならない。
応用編では使用できるプレースホルダのバリエーションを解説する。