echoでpongo2のtemplateを使う

Goのウェブフレームワークとして最近はechoを使っている. echoはmiddlewareも充実しているし便利なのだが,いざhtmlを吐き出そうと思うと,echoがサポートしてくれることは少ない.

jsonを出している限り,あまり困らないのだが.

そこで,以前使っていたpongo2というdjango風なテンプレートエンジンを使おう,というか使っていた. そのときに,github.com/echo-contrib/pongor というのを使っていたのだが,このパッケージが最近github上から消えた.

完全に404だ.

仕方ないので自作する

というわけで,このくらいは自作しようと思って自作した.

github.com

実は他にもいくつかコレ系のパッケージはあるのだが,必要なこととして,

  • カスタムのpongo2-addonsが提供するfilterを登録できること
  • テンプレートの探索ディレクトリを任意に設定できること

というのが要件としてあって,これを満たすものが見つからなかった.

というかみんなgolang大好きだけど,テンプレートエンジンとかどうしてるの? 素の html/template だけだと,いろいろ大変じゃない?

使い方

READMEの通り.

import (
    "github.com/h3poteto/pongo2echo"
    "github.com/labstack/echo"
)

func main() {
    render := pongo2echo.NewRenderer()
    e := echo.New()
    e.Renderer = render

    e.GET("/", func(c echo.Context) error {
        // index.html.tpl is located in templates/index.html.tpl
        return c.Render(http.StatusOK, "index.html.tpl",  map[string]interface{}{"title": "Index"})
    })
    e.Logger.Fatal(e.Start(":1323"))
}

ちなみにデフォルトだと ./templates からテンプレートを探してくる.

変更したい場合は,

render.AddDirectory("server/templates")

とかしよう.

同じくfilterの登録も,

render.AddFilter("filterName", customFilterFunc)

とかすればいける. 注意点として,pongo2はタグがついている3.0.0ではなくmasterのソースを使おう.

goなので,そのへんはちゃんとgithubのmasterをつかうようになっているとは思うが,depで依存解決するときなど注意だ.

filterについて

このpackageではないのだが,filterについて少しだけ注意点がある.

import (
    "github.com/flosch/pongo2"
    _ "github.com/flosch/pongo2-addons"
)

func customFilterFunc(in *pongo2.Value, param *pongo2.Value) (out *pongo2.Value, err *pongo2.Error) {
    // ...
}

というようなfilterを作ると思う. ただ,flosch/pongo2-addons が依存している,russross/blackfriday が最近更新され,v2.0.0が出ている.

それによって,russross/blackfriday のv2.0.0では,現状の flosch/pongo2-addons が動かない(masterにはまだその変更が入っていないため,masterなら動く).

https://github.com/flosch/pongo2-addons/blob/master/filters.go#L43

ここで,エラーが出る.

# github.com/h3poteto/fascia/vendor/github.com/flosch/pongo2-addons
vendor/github.com/flosch/pongo2-addons/filters.go:43:35: undefined: blackfriday.MarkdownCommon

そのため,現状これを動かすためには,dep等で明示的にblackfridyへの依存とバージョンを明記しておこう.