htmlのtemplate【Go】
概要
http.ResponseWriterにセットする内容量が多い場合(複数行に渡るhtml記述)、
template機能を使うべきです。
事前にhtmlファイル(今回はview.html)を同階層に作成し、
後で示すコードを記述したmain.goを実行します。
htmlファイルの記述
まずはtemplateとなるhtmlファイルの記述方法です。
基本的には通常のhtmlと同じ書き方ですが、
goファイルから渡されるPage structの中身などを表示したい場合に、工夫が必要です。
<!-- 「.<フィールド名>」で、http.ResponseWriterに登録したgoファイルの変数を表示 --> <h1>{{.Title}}</h1> <!-- editは別途必要。文字列の中にも「.<フィールド名>」を記述できる --> <p><a href="/edit/{{.Title}}">Edit</a></p> <!-- 「printf %s .<フィールド名>」で、byte配列をキャスト --> <div>{{printf "%s" .Body}}</div>
上記のように、structの場合、「.<フィールド名>」と記述すれば、
template.ParseFiles("~.html").Execute(w http.ResponseWriter, i interface{}) で登録した
goファイルからの内容を表示することができます。
ただし、byte配列の場合は「printf %s .<フィールド名>」としてstring型にキャストします。
goファイルの記述
http.HandleFunc()で登録するHandler関数の処理を
templateを使うように記述します。
type Page struct { Title string Body []byte } func load(title string) (*Page, error) { filename := title + ".txt" body, err := ioutil.ReadFile(filename) if err != nil { return nil, err } return &Page{Title: title, Body: body}, nil } func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) { t, _ := template.ParseFiles(tmpl + ".html") // 同階層にあるhtmlファイルを読み込む t.Execute(w, p) // 読み込んだ内容をhttp.ResponseWriterに登録する } func viewHandler(w http.ResponseWriter, r *http.Request) { title := r.URL.Path[len("/view/"):] p, err := load(title) if err != nil { log.Fatalln(err) } // fmt.Fprintf(w, "<h1>%s</h1><div>%s</div>", p.Title, p.Body) // この書き方だと、内容が多い場合に不便 renderTemplate(w, "view", p) } func main() { http.HandleFunc("/view/", viewHandler) log.Fatalln(http.ListenAndServe(":8080", nil)) }