Goのテンプレートの中で関数を使い、その関数に引数を渡す
GoでMVCなアプリを書くときに重宝するであろう、templateパッケージ
そのtemplateパッケージを使用してGoでテンプレートを書き、その中で関数を呼び出し、引数に構造体のフィールド上に存在するスライスの要素を渡す
GoのtemplateのPipelinesを理解するのにも役に立つと思うのでメモ
GoのTemplateでスライスを扱うには
Goのtemplateのあらかじめ定義されたグローバル関数であるindexを使用する
indexは
最初の引数を続く引数でインデックスした結果を返します。
例えば"index x 1 2 3"はGoの文法では x[1][2][3]となります。
インデックスされる値はマップ、スライス、配列である必要があります。
(引用元:http://golang-jp.org/pkg/text/template/)
GoののTemplateで関数を扱うには
FuncMapで関数の名前と関数のmapを定義する
詳しくは、後述のコードを参照
GoのPipelines(パイプライン)とは
パイプラインはパイプライン文字'|'で区切ってコマンドをつなげることによって「連鎖」させることができます。 連鎖されたパイプラインでは、各コマンドの結果は次のコマンドへ最後の引数として渡されます。 パイプラインにおける最後のコマンドの出力がそのパイプラインの値になります。
(引用元: http://golang-jp.org/pkg/text/template/)
例えば、aというコマンドとbというコマンドが存在した場合、
a | b
というコードは、Goでは、aのコマンドの実行結果が、bのコマンドの最後の引数となる
実装してみる
package main
import (
"html/template"
"net/http"
"log"
)
// メイン関数
func main() {
// ハンドラをバンドル
http.HandleFunc("/", Handler)
// リスナー
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
// テンプレートを生成
func Handler(w http.ResponseWriter, r *http.Request) {
// 構造体Programを生成
p := &Program{Languages:[]string{"Go", "Java", "Python", "JavaScript"},}
// 関数を名前をつけてtemplateのFuncMapに登録
funcMap := template.FuncMap{
"judgeLangType" : JudgeLangType,
}
// テンプレート部分
text := `
Go : {{ index .Languages 0 | judgeLangType}}
Java : {{ index .Languages 1 | judgeLangType}}
Python : {{ index .Languages 2 | judgeLangType}}
JavaScript : {{ index .Languages 3 | judgeLangType}}
`
// テンプレートをパースして、http.ResponseWriterに書き込み
tmpl := template.Must(template.New("calculator").Funcs(funcMap).Parse(text))
tmpl.Execute(w, p)
}
// 構造体
type Program struct {
Languages []string
}
// 言語を引数に受けて、その言語の型を返す
func JudgeLangType(lang string) string{
switch lang {
case "Go", "Java":
return "Static"
case "Python", "JavaScript":
return "Dynamic"
default:
return "unknown"
}
}
実行結果
Go : Static
Java : Static
Python : Dynamic
JavaScript : Dynamic
上記のコードのテンプレート部分である以下に注目する
// テンプレート部分
text := `
Go : {{ index .Languages 0 | judgeLangType}}
Java : {{ index .Languages 1 | judgeLangType}}
Python : {{ index .Languages 2 | judgeLangType}}
JavaScript : {{ index .Languages 3 | judgeLangType}}
`
Go : {{ index .Languages 0 | judgeLangType}}
-
index .Languages 0
で、構造体Program
のフィールドLanguage
のスライスの0番目の要素を表している -
|
で、パイプラインを表している -
judgeLangType
は、template.FuncMap
で登録した関数を表している
これは、 |
の左側の index .Languages 0
の結果(Languagesスライスの0番目の要素)が |
の右側の judgeLangType
関数の引数になっている
参考にさせていただいたサイト
http://golang-jp.org/pkg/text/template/#FuncMap
https://gohugo.io/templates/go-templates/