2011年12月28日水曜日

Go言語のtemplate.Setを使う

書籍「Go言語プログラミング入門 on Google App Engine」でも記述していない事なので
Blogに残しておこうと思います。

Google App EngineのアプリケーションはWebアプリケーションなので、HTMLを
出力する事が多いと思います。(WebAPIを作成する場合はテキストベースかもしれませんが)
HTMLのタグで面倒なヘッダ部分、フッタ部分など共通化したい所があったりすると
思います。
書籍では、Templateパッケージを利用して、HTMLファイルに変換タグを追加し、プログラムで変換タグを置き換えるというアプローチでHTMLを出力させています。しかも、Templateが一つの例が載っていますが、複数ページを作成するという事がなかったので
登場することがありませんでした。

前置きはこの辺にして、複数のページを作成する場合、ヘッダとフッタに関しては共通化される事が多いかと思います。Go言語でもその機能は提供されていますので、サンプルを書き残しておきたいと思います。

まず、HTMLの部分です。

ヘッダ
  
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Set Sample</title>
</head>
<body>

フッタ
<hr>
Footer
</body>
</html>

ボディ(全体)
{{define "body"}}{{template "header"}}
<h1>Set Sample</h1>
{{template "footer"}}{{end}}

ソースコード
package setsample

import (
 "http"
 "template"
)

func init() {
 http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
 header := template.Must(template.New("header").ParseFile("header.html"))
 footer := template.Must(template.New("footer").ParseFile("footer.html"))
 body := template.SetMust(template.ParseSetFiles("body.html"))

 body = body.Add(header, footer)

 if err := body.Execute(w, "body", "no data needed"); err != nil {
  http.Error(w, err.String(), http.StatusInternalServerError)
 }
}

ポイントは、headerとfooterはtemplateとして読み込み、bodyをSetとして読み込む所です。
Setにはtemplateを追加する事ができるので、bodyにheaderとfooterのtemplateのタグを追加しておき、プログラムでAddします。

最後、Setに関しては名前を指定しないと出力(Execute)できないようなので、defineタグをbodyに追加しています。

これにより、HTML出力の処理が1回で済むようになります。