Martiniのrender+ sessionauthでテンプレートからログイン中のユーザーを取得する
martini-contrib/render と martini-contrib/sessionauth を組み合わせて使っている時に毎回各ハンドラでユーザーをrenderに渡していた。
関係ないところは省いてあるけどこんな感じ
func main() { m := martini.Classic() m.Use(sessionauth.SessionUser(GenerateAnonymousUser)) m.Use(render.Renderer()) m.Get("/private", GetPrivate) m.Run() } func GetPrivate(r render.Render, user sessionauth.User) { r.HTML(200, "private", map[string]interface{}{"User": user.(*UserModel)}) }
private.tmpl
{{if .User.IsAuthenticated }} ログイン済み {{end}}
まぁこれでも良いのだけどいちいち書くのが面倒なのでテンプレート関数を定義してユーザーを取得できるようした。
html/template
の機能だけどもちろんrender
から使える。
func main() { m := martini.Classic() m.Use(sessionauth.SessionUser(GenerateAnonymousUser)) // ダミーの関数を追加しておく m.Use(render.Renderer(render.Options{ Funcs: []template.FuncMap{{"currentUser": func() *UserModel { return nil }}}, })) // ミドルウェアで関数を上書きする m.Use(func(r render.Render, u sessionauth.User) { r.Template().Funcs(template.FuncMap{ "currentUser": func() *UserModel { return u.(*UserModel) }, }) }) m.Get("/private", GetPrivate) m.Run() } func GetPrivate(r render.Render, user sessionauth.User) { r.HTML(200, "private", nil) }
private.tmpl
{{if currentUser.IsAuthenticated }} ログイン済み {{end}}
あまり良い方法ではない。
まずダミーの関数で名前だけを登録しておいて、次にミドルウェアとしてsessionauth
からユーザーを取り出しrender
のテンプレート関数を上書きするという動きになっている。
元ネタ Allow injecting into helper functions · Issue #3 · martini-contrib/render · GitHub