Help us understand the problem. What is going on with this article?

Go言語のテンプレート機能について

More than 1 year has passed since last update.

概要

go言語に標準で搭載されているテンプレート機能について紹介します。
テンプレート機能を使うことで、ロジックとデザインを分離することが出来ます。
変数の埋め込み、ループ、条件分岐などが出来ます。

ただし、それほど多機能ではないため使い所は限られるでしょう。
例えばメールではJavascriptが使えないため使用に適しています。

複雑なことはできませんが独自関数を作成できるため、何かをやろうとする場合は逐次独自関数を作成していくことになります。

packageについて

Go言語には組込みのテンプレート・パッケージとして、 text/templatehtml/template パッケージが搭載されています。

html/template パッケージはtext/template をラップしたもので、同じインターフェースを提供し、コードインジェクション対策を施した安全なHTMLを生成します。

出力が HTML の場合は常に html/template を用いるべきです。

基本的な使い方

//テンプレートを用意
textBody := `
{{define "base"}}
    Hello! {{.Name}}
    {{.Age}}歳ですね
{{end}}
`
//埋め込み変数
params := map[string]string{
    "Name": "たろう",
    "Age": "23",
}

t, _ := template.New("base").Parse(textBody)
t.Execute(os.Stdout, params)

テンプレート内の記述方法

//Goからの変数を受け取るには .変数名 となります
{{.Name}}

//テンプレート内で変数を作成できます。この場合、$変数名 になります
{{$count := 23}}
{{$count}}

//ループ処理
//break, continueなどの機能はない
{{range $index, $offer := .Offers}}
    {{$index}}  //0, 1, 2 ...
    {{$offer.Name}} //構造体の中身へのアクセス
{{end}}

//条件分岐
{{ if gt i 1 }}
    i > 1 です
{{end}}

//上記同様の書き方で、以下の比較関数が使える
//引数はスペース区切りで与える
eq
  arg1 == arg2
ne
  arg1 != arg2
lt
  arg1 < arg2
le
  arg1 <= arg2
gt
  arg1 > arg2
ge
  arg1 >= arg2

文字列操作

fmt.printf が使えますので、文字列の連結はできます

{{$body := printf "%s%s" $index "番目です"}}

独自関数について

上記にかかれていること以外は基本的できず、四則演算も出来ません。やる場合は独自関数を定義する必要があります
独自関数はGo側で定義し以下のようにテンプレート側に渡します。

funcMap := template.FuncMap{
    "add":  func(a, b int) int { return a + b },
}

t, _ := template.New("base").Funcs(funcMap).Parse(textBody)
t.Execute(os.Stdout, params)

//テンプレート側では以下のように使用できる
{{add 5 2}} //7
{{$count := add 4 2}}   //変数にわたすこともできる
{{$count}}  //6

搭載された全関数。詳しくはドキュメントを参照

https://golang.org/pkg/text/template/

funcs
var builtins = FuncMap{
    "and":      and,
    "call":     call,
    "html":     HTMLEscaper,
    "index":    index,
    "js":       JSEscaper,
    "len":      length,
    "not":      not,
    "or":       or,
    "print":    fmt.Sprint,
    "printf":   fmt.Sprintf,
    "println":  fmt.Sprintln,
    "urlquery": URLQueryEscaper,

    // Comparisons
    "eq": eq, // ==
    "ge": ge, // >=
    "gt": gt, // >
    "le": le, // <=
    "lt": lt, // <
    "ne": ne, // !=
}
ryokwkm
エンジニアをやめて俳優として生きていこうとしているダメ人間 ちょっと中二っぽいのが特徴
http://ryokwkm.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away