title: Conditional rendering of HTML in Golang layout.tpl by session variable
body: <p>I use Gorilla sessions (via negroni-sessions) to store my <strong>user</strong> sessions in cookies. I also use <code>github.com/unrolled/render</code> for my HTML template rendering:</p>
  
  <p><strong>main.go:</strong></p>
  
  <pre><code>    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")
  
      }
  </code></pre>
  
  <p>As you can see above, I use a <strong>layout.html</strong> master HTML template which is included when any page renders, like my home page:</p>
  
  <pre><code>    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)
      }
  </code></pre>
  
  <p>In my <strong>layout.html</strong> master HTML template, I want to render an admin menu but only if the current user is an admin:</p>
  
  <p><strong>layout.html</strong>: </p>
  
  <pre><code>&lt;!doctype html&gt;
  &lt;html&gt;
    &lt;head&gt;
      &lt;meta charset="utf-8"&gt;
        &lt;title&gt;{{ template "title" . }}&lt;/title&gt;
          ...
    &lt;/head&gt;
  
    &lt;body&gt;
      ...
      &lt;!--Main Menu--&gt;
        &lt;nav class="menu"&gt;
           &lt;ul class="catalog"&gt;
               &lt;li class="has-submenu"&gt;
                  {{ RenderMenuCategories }}
               &lt;/li&gt;
               &lt;li&gt;&lt;a href="javascript:void(0)"&gt;Blog&lt;/a&gt;&lt;/li&gt;
               &lt;li&gt;&lt;a href="javascript:void(0)"&gt;Company&lt;/a&gt;&lt;/li&gt;
  
               {{ RenderAdminMenu }}
  
           &lt;/ul&gt;
        &lt;/nav&gt;
  </code></pre>
  
  <p>...</p>
  
  <p>My issue is that the above template helper function <code>RenderAdminMenu()</code> doesn't have access to the HTTP Request object and therefore cannot access the <strong>User</strong> session object to determine if the user is admin. </p>
  
  <p>I can pass the User object into the template context via the Home page handler, and use an <code>if</code> statement RenderAdminMenu() function, like this</p>
  
  <pre><code>{{ if .User.IsAdmin }}
     {{ RenderAdminMenu }}
  {{ end }}
  </code></pre>
  
  <p>...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?</p>
  
  <p>I was thinking perhaps there might be a way to access some kind of global <code>Context</code> object from within <code>RenderAdminMenu()</code> (or layout.html) which contains the <code>Request</code> details (like you can in ASP.NET)</p>