render icon indicating copy to clipboard operation
render copied to clipboard

Allow injecting into helper functions

Open codegangsta opened this issue 12 years ago • 6 comments

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

codegangsta avatar Feb 08 '14 23:02 codegangsta

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

ahall avatar Mar 28 '14 00:03 ahall

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

sevkin avatar Apr 07 '14 19:04 sevkin

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

seedifferently avatar Apr 11 '14 18:04 seedifferently

Yep, now just waiting feedback from the mighty @codegangsta

ahall avatar Apr 11 '14 21:04 ahall

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.

codegangsta avatar Apr 11 '14 22:04 codegangsta

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
        }
    }
}

scottkf avatar Apr 11 '14 22:04 scottkf