【Golang】ExecuteTemplate関数で渡した値を、scriptタグ内で参照する方法
経緯
Goのhtml/template
パッケージのExecuteTemplate
関数の第二引数に何らかの値を代入することで、描画するhtml
に値を渡すことができ、html
のタグ内に展開する例がよく紹介されています。しかし、渡した値が配列やスライスの場合、script
タグ内で参照する時と、script
タグ外で参照する時で記法が少し異なってきます。
script
タグ内とscript
タグ外で参照方法が同じ場合
以下の2つの例のように1つのデータを渡す時は、script
タグ内とscript
タグ外で参照方法は変わりません。
なお、script
タグ内で{{.}}
を使うとIDEの設定によってはエラー判定となりますが、問題なく動作します。
①単純な値を渡す場合
hoge := "hoge" tpl := template.Must(template.ParseFiles("./templates/test.html")) tpl.ExecuteTemplate(w, "test.html", hoge)
<body> <p>{{.}}</p> //hoge </body> <script> console.log({{.}}) //hoge </script>
②構造体を1つ渡す場合
type Person struct { //json変換用のキー名の設定はなくてもok Name string `json:"name"` Age int `json:"age"` Height int `json:"height"` } NewPerson := new(Person) NewPerson.Name = "John" NewPerson.Age = 30 NewPerson.Height = 180 tpl := template.Must(template.ParseFiles("./templates/test.html")) tpl.ExecuteTemplate(w, "test.html", NewPerson) }
<body> <p>{{.}}</p> //{John 30 180} <p>{{.Name}}</p> //John <p>{{.Age}}</p> //30 <p>{{.Height}}</p> //180 </body> <script> console.log({{.}}) //{name: "John", age: 30, height: 180} //json用のキー名を設定している場合も、元の構造体のフィールド名を使う! console.log({{.Name}}) //John console.log({{.Age}}) //30 console.log({{.Height}}) //180 </script>
scriptタグ内とscriptタグ外で参照方法が異なる場合
しかし、配列やスライスといったデータを渡す場合、参照方法が異なってきます。script
タグ外では{{index . 0}}
や{{range .}}
{{end}}
などで参照を行いますが、script
タグ内では{{.}}[0]
、{{.}}[1]
というように{{.}}[n]
で配列の要素を取得する形でまず参照を行います。配列の要素が構造体の場合、{{.}}[0].name
というようにキー名を指定し、値を取得することができます。
type Person struct { //json変換用のキー名の設定はなくてもok Name string `json:"name"` Age int `json:"age"` Height int `json:"height"` } func testHandler(w http.ResponseWriter, r *http.Request) { NewPerson1 := new(Person) NewPerson1.Name = "John" NewPerson1.Age = 30 NewPerson1.Height = 180 NewPerson2 := new(Person) NewPerson2.Name = "Mike" NewPerson2.Age = 25 NewPerson2.Height = 175 Slice := []*Person{NewPerson1, NewPerson2} tpl := template.Must(template.ParseFiles("./templates/test.html")) tpl.ExecuteTemplate(w, "test.html", Slice)
<body> <p>{{.}}</p> //[0xc000169240 0xc000169260]などと表示される。 <p>{{index . 0}}</p> //{John 30 180} <p>{{(index . 0).Name}}</p> //John </body> <script> console.log({{.}}) //↓(2) [{…}, {…}] //→0: {Name: "John", Age: 30, Height: 180} //→1: {Name: "Mike", Age: 25, Height: 175} //→length: 2 //→__proto__: Array(0) console.log({{.}}[0]) //{Name: "Mike", Age: 25, Height: 175} console.log({{.}}[1]["name"]) //Mike ※hashの値を取得する形式でも可 console.log({{.}}[1].name) //Mike console.log({{.}}[1].age) //25 console.log({{.}}[1].height) //175 </script>
ちなみに、例では構造体の定義でjson変換時のキー名の設定を追加していますが、設定しなくても値の取得が行えます。その場合はそのままフィールド名をキー名に使用して個々の値を取得できます。
ExecuteTemplate関数で渡される値について
html/templateパッケージの仕様書には詳しい記載はないのですが、これまでの例を見た限り、ExecuteTemplate
関数での値渡しは以下の規則で行われるようです。
①ただの変数・配列などの単純な部分はそのまま渡す。
②構造体・連想配列などの部分があれば、json形式に変換する。
(json変換時のキー名が設定されていなければ、フィールド名をそのまま使用する)
注意点
値の参照でエラーが起きると、scriptタグ内の関数が全て実行されなくなります。