【Go】templateの基礎的使い方

GoでWebプログラミングを学んでます。

今回はtemplateの使い方の紹介です。

基礎的な使い方

まずはソースコードから。
main.go

package main

import (
        "html/template"
        "net/http"
)

func process(w http.ResponseWriter, r *http.Request){
        t := template.Must(template.ParseFiles("tmpl.html"))
        m := "Helooooooo!!!" // <--- tmpl.html の {{ . }} に表示されるデータ
        t.Execute(w, m)
}

func main(){
        server := http.Server{
                Addr: "127.0.0.1:8080",
        }
        http.HandleFunc("/process", process)
        server.ListenAndServe()
}

tmpl.html

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Go template work</title>
  </head>
  <body>
    {{ . }}  <!-- <--- ここにデータが表示される-->
  </body>
</html>

これを実行して localhost:8080/process をブラウザで確認すると

Helooooooo!!!

っと表示されます。

でこれは、文字列以外に数値でも構造体でも配列でもハッシュでも m:= ... のところでデータを渡せば表示することができます。

template.Must

余談ですがtemplate.ParseFilesの結果をtemplate.Mustでラップしてます。
これ知らなかったのですが、エラー処理を省略するためです。
template - The Go Programming Language
ParseFilesの結果はエラー結果も返してしまいますが、そのエラー処理を省略させてしまうのがMustです。
template - The Go Programming Language

構造体を渡す

とりあえず構造体を渡す

そんでこのデータを渡すときは構造体を渡してやると何かと使いやすいので構造体を使うことが多いです。
以降修正箇所は部分的に提示します。

type Member struct {
        Id   int
        Name string
}

func process(w http.ResponseWriter, r *http.Request){
        t := template.Must(template.ParseFiles("tmpl.html"))
        m := Member{   // <--- 構造体で渡す
                Id: 123,
                Name: "bob",
        }
        t.Execute(w, m)
}
  <body>
    {{ .Id }} <!-- 構造体MemberのIdを表示 -->
  </body>

構造体で配列を渡す

例えば下記のように構造体の中の配列を表示させるには、rangeを使うと表示できます。

type Member struct {
        Items   []Item
}
type Item struct {
        Id      int
        Name    string
}

func process(w http.ResponseWriter, r *http.Request){
        t := template.Must(template.ParseFiles("tmpl.html"))
        m := Member{
                Items: []Item{
                        Item{Id: 123, Name: "bob"},
                        Item{Id: 456, Name: "tom"},
                        Item{Id: 789, Name: "mike"},
                },
        }
        t.Execute(w, m)
}
  <body>
    <ul>
    {{ range .Items }}
       <li>{{ .Id }} - {{ .Name }}</li>
    {{ end }}
    </ul>
  </body>
・123 - bob
・456 - tom
・789 - mike

range は indexも使える

そしてこのrangeはindexも使えます。
main.goは変えずにtmpl.htmlを修正します。

  <body>
    <ul>
    {{ range .Items }}
       <li>{{ .Id }} - {{ .Name }}</li>
    {{ end }}
    </ul>
    <ul>
    {{ range $i, $v := .Items }}
       <li>{{ index $.Items $i }} : {{ $v }}</li>
    {{ end }}
    </ul>
  </body>
・123 - bob
・456 - tom
・789 - mike

・{123 bob} : {123 bob}
・{456 tom} : {456 tom}
・{789 mike} : {789 mike}

なかなか使えますね。