martini-contrib / render

Martini middleware/handler for easily rendering serialized JSON, XML, and HTML template responses.
MIT License
245 stars 57 forks source link

Allow injecting into helper functions #3

Open codegangsta opened 10 years ago

codegangsta commented 10 years ago

from @ahall

The goal is to be able to do something like this:

m.Use(render.Renderer(render.Options{
    Layout:    "layout",
    Funcs: []template.FuncMap{
        {
            "myCustomFunc": func(r *http.Request, m MyInjectedStuff) string {
                                    // Do something with r and m
                return "My custom function"
            },
        },
    },
}))

Original issue: https://github.com/codegangsta/martini-contrib/issues/99

ahall commented 10 years ago

Hi @codegangsta. Have you had time to think about this?

sevkin commented 10 years ago

very useful. it will be possible to inject render.Render?

seedifferently commented 10 years ago

Definitely needed. I'd also like to be able to inject values from sessions.Session.

ahall commented 10 years ago

Yep, now just waiting feedback from the mighty @codegangsta

codegangsta commented 10 years ago

Yeah this would be great to have. There are some unfortunate limitation as to how Go's template library works with helper functions. There may be some clever ways to do so. But most of the solutions seem overly hacky.

scottkf commented 10 years ago

The only thing that appears to work is defining a stub method, then including a middleware overriding the template maps (which injects anything I need, like session, etc). The only thing that might make it easier is not having to define the method in the beginning, but golang's text/template doesn't appear to work that way. Might be some hackish way to implement it though.

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

var funcHeader = []template.FuncMap{
    {
        "set_data": func(context map[string]interface{}) string {
            return ""
        },
    }
}

func HelperFuncs() martini.Handler {
    return func(r render.Render, u *users.UserProfile, s sessions.Session) {
        r.Template().Funcs(funcDefinitions(u, s))
    }
}

var funcDefinitions = func(u *users.UserProfile, s sessions.Session) template.FuncMap {
    return template.FuncMap{
        "set_data": func(context map[string]interface{}) string {
            do something with session
        }
    }
}