I use Gorilla sessions (via negroni-sessions) to store my user sessions in cookies. I also use github.com/unrolled/render
for my HTML template rendering:
main.go:
package main
import (
...
"github.com/codegangsta/negroni"
"github.com/goincremental/negroni-sessions"
"github.com/goincremental/negroni-sessions/cookiestore"
"github.com/julienschmidt/httprouter"
"github.com/unrolled/render"
...
)
func init() {
...
ren = render.New(render.Options{
Directory: "templates",
Layout: "layout",
Extensions: []string{".html"},
Funcs: []template.FuncMap{TemplateHelpers},
IsDevelopment: false,
})
...
}
func main() {
...
router := httprouter.New()
router.GET("/", HomeHandler)
// Add session store
store := cookiestore.New([]byte("my password"))
store.Options(sessions.Options{
//MaxAge: 1200,
Domain: "",
Path: "/",
})
n := negroni.New(
negroni.NewRecovery(),
sessions.Sessions("cssession", store),
negroni.NewStatic(http.Dir("../static")),
)
n.UseHandler(router)
n.Run(":9000")
}
As you can see above, I use a layout.html master HTML template which is included when any page renders, like my home page:
package main
import (
"html/template"
"github.com/julienschmidt/httprouter"
)
func HomeHandler(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
var model = struct {
CatalogPicks []PromotionalModelList
ClearanceItems []Model
}{
CatalogPicks: GetCatalogPicks(),
ClearanceItems: GetClearanceItems(),
}
ren.HTML(w, http.StatusOK, "home", model)
}
In my layout.html master HTML template, I want to render an admin menu but only if the current user is an admin:
layout.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{ template "title" . }}</title>
...
</head>
<body>
...
<!--Main Menu-->
<nav class="menu">
<ul class="catalog">
<li class="has-submenu">
{{ RenderMenuCategories }}
</li>
<li><a href="javascript:void(0)">Blog</a></li>
<li><a href="javascript:void(0)">Company</a></li>
{{ RenderAdminMenu }}
</ul>
</nav>
...
My issue is that the above template helper function RenderAdminMenu()
doesn't have access to the HTTP Request object and therefore cannot access the User session object to determine if the user is admin.
I can pass the User object into the template context via the Home page handler, and use an if
statement RenderAdminMenu() function, like this
{{ if .User.IsAdmin }}
{{ RenderAdminMenu }}
{{ end }}
...but since I am using a master template, I would have to do that from every web page on the site. Is there a more efficient way?
I was thinking perhaps there might be a way to access some kind of global Context
object from within RenderAdminMenu()
(or layout.html) which contains the Request
details (like you can in ASP.NET)