読者です 読者をやめる 読者になる 読者になる

Golang+Martiniを使ってHTMLテンプレート(html/template)内で四則演算を行う方法

MartiniでWebアプリ作ってるときに一瞬詰まったので、紹介します。
HTMLテンプレートを使っていると、テンプレート内で変数の演算を行いたいときがあると思います。
例えば、{{.IntValue}}を簡単な計算をしてから表示したいような場合です。
1を加算したい場合、単純に考えると{{.IntValue+1}}のようにすると思います。
しかし、Golangのテンプレート内では足し算や引き算等の演算が標準ではできません。
(Rubyならできるのですが...)
Golangのテンプレート内で演算を行うには、テンプレート用の関数を作成して登録する必要があります。template.FuncMapで関数の登録ができ、Martiniでもこれを使って登録をします。
main.go

package main

import (
	"github.com/codegangsta/martini-contrib/render"
	"github.com/go-martini/martini"
	"html/template"
)

type Value struct {
	IntValue int
}

func main() {
	m := martini.Classic()
	// render html template
	m.Use(render.Renderer(render.Options{
		Funcs: []template.FuncMap{ // レンダラにテンプレート関数を登録します。
			{
				"add": func(a, b int) int { return a + b },
				"sub": func(a, b int) int { return a - b },
				"mul": func(a, b int) int { return a * b },
				"div": func(a, b int) int { return a / b },
			},
		},
	}))
	m.Get("/", top)
        m.Run()
}

// トップページ
func top(ren render.Render) {
        var value Value
        value.IntValue = 10
	ren.HTML(200, "top", value) // top.tmplにvalueを渡してレンダリングします。
}

今回のポイントは以下の部分です。

m.Use(render.Renderer(render.Options{
		Funcs: []template.FuncMap{
			{
				"add": func(a, b int) int { return a + b },
			},
		},
	}))

render.Optionsに以上のようにして関数を定義して登録することができます。

top.tmplというテンプレートに値を渡します。templatesディレクトリを作成して、その中にtop.tmplファイルを作ってください。

top.tmpl

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8" />
        <title>Untitled Document</title>
    </head>
    <body>
      <h3>{{.IntValue}}足す1は{{add .IntValue 1}}です。</h3>
    </body>
</html>

関数は{{関数名 引数1 引数2}}のようにして使います。
go run main.goを実行して、http://localhost:3000にアクセスすると結果が表示されます。
f:id:ax3n_data:20150506185538p:plain
こんな感じでテンプレート内で演算することができます。

ちなみにテンプレート内で変数を宣言して使うこともできます。
テンプレート内変数を使う場合
top.tmpl

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8" />
        <title>Untitled Document</title>
    </head>
    <body>
      {{$addValue:=1}}
      <h3>{{.IntValue}}足す{{$addValue}}は{{add .IntValue $addValue}}です。</h3>
    </body>
</html>

応用すると色々なことができそうですね。
Goのテンプレートでは独自の関数を定義することで、様々な処理を追加することができます。
今日もいいお天気ですね。Golangでよい午後を!
参考リンク