golang製フレームワークのMartiniで簡単にHTMLとかをレンダリングしてみる

前回の記事の続きというか、Martiniの使い方のちょっとした紹介です。例によって公式に書いてあるものほぼそのものですけど。

で、今日やる内容は「html/templateパッケージを使うより楽にHTMLとかレンダリングする方法」です。まあ、一言で言ってしまえばmartini-contribっていうMartiniのアドオンを使うやり方なんですが。

前準備

何はなくともgo getです。

今回はmartini-contrib/renderパッケージを使用しますので、以下のようになります。

go get github.com/codegangsta/martini
go get github.com/codegangsta/martini-contrib/render

ファイル構成と中身

では実際のコードを記載する前にファイル構成を示しておきます。

├── server.go
└── templates
    └── hello.tmpl

前回と同じく、中核のコードはserver.goに記載するものとして考えてください。

今回はテンプレートとなるファイルを用意する必要があります。それがtemplatesディレクトリ下のhello.tmplです。公式のものそのままですが、中身はこんな感じだとして進みます。

gist8519450

では次にserver.goの中身です。

gist8518799

公式に書いてあるものほぼそのままですが、前回の記事の内容を受けているので、ハンドラを切り分けてhello関数としています。

これで前回と同じようにgo run server.goとやってhttp://localhost:3000/ にアクセスすれば、Hello master!と表示されるはずです。

今回のポイント

今回のポイントはmiddlewareであるmartini-contrib/renderパッケージを使っているところで、インポートした後m.Use()の引数にmiddlewareを渡してやればそのmiddlewareを使えるようになります。

このmartini-contrib/renderパッケージを使ってやれば、hello関数の中を見て分かるように、render.Render.HTML()に引数を3つ渡してやれば、あらかじめ用意してあるテンプレート(デフォルトではtemplatesディレクトリ下のtmplファイル群)を使用してHTMLをレンダリングしてくれます。

第一引数は返すべきステータスコード、第二引数は使用したいテンプレートファイルの名前、第三引数はテンプレートをレンダリングするときに使用したい情報です*1

今回の応用

middlewareを登録するときにオプションの情報を渡してやることで挙動を変えることができます。

gist8518873

この時のファイル構成はこうです。

├── server.go
└── templates
    ├── hello.tmpl
    └── layout.tmpl

詳しくは公式の情報参照。主だったものだけ以下で紹介します。

テンプレートディレクトリの指定

デフォルトではルート下にあるtemplatesディレクトリの.tmplファイルをテンプレート候補として探すようになっていますが、以下のオプションを指定するとテンプレートディレクトリを別のものに変更することが出来ます。

m.Use(render.Renderer(render.Options{
        Directory:  "another-templates",
    }))

レイアウトの指定

レイアウトの元になるファイルを指定できます。

m.Use(render.Renderer(render.Options{
        Layout:     "layout",
    }))

こう書くとlayout.tmplをレイアウトの元として指定します。

で、layout.tmplを以下のように書くとyield functionを使用したところにテンプレートをレンダリングします。まあ要するにJinja2とかでやるテンプレートの継承とかでやるような「レイアウトを設定するファイルを定義できる」ということです。多分。

gist8519662

テンプレートファイルの拡張子の追加・変更

デフォルトでは.tmplしかテンプレートとして解釈されないみたいですが、オプションで拡張子を追加すれば.htmlもテンプレートとして使えるようになります。エディタの都合とか考えると.htmlの方がいいという場合は多いと思うのでやってみたらいいと思います。

m.Use(render.Renderer(render.Options{
        Extensions: []string{".tmpl", ".html"},
    }))

他のオプションは公式リポジトリの説明でも見てください。ぶっちゃけ使ったことあるものしか紹介できないので。

最後に

MartiniはPythonで言えばFlaskみたいなもののように感じますが、こうやってmiddlewareを使えば機能も増やせるところがいいかなと思います。自分で作ることも出来るみたいですし。*2

今回はHTMLのレンダリングだけでしたが、同じやり方でjsonレンダリングも簡単にできるみたいなのでAPIサーバとかも割合簡単に実装できるかもしれません。

*1:html/templateの使い方参照、というか私もよく分かってません

*2:まだやり方分かりませんけど