Description

If you have middleware (using r.Use()), you can set keys through the method ctx.Set(k, v) which puts them into ctx.Keys. This sets the expectation of when using:

ctx.HTML(http.StatusOK, "account.html", gin.H{
    "Name":  user.Name,
    "Email": user.Email,
})

You expect that the map gin.H's entries will be applied on top of ctx.Keys, however, it overwrites them. Here is my Use method:

r.Use(func(ctx *gin.Context) {
// Set common context values
ctx.Set("Title", "My website")

if cookieId, err := ctx.Cookie(data.COOKIE_SESSION); err == nil {
    ctx.Set("SignedIn", len(cookieId) > 0)
}
})

Here are some of my routes:

Route /

r.GET("/", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "index.html", ctx.Keys)
})

Route about

r.GET("/about", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "about.html", gin.H{})
})

Inside each one I simply output the context using {{.}}, the context is as follows:

  • Route /: CTX: map[SignedIn:true Title:My website]
  • Route about: CTX: map[]

Multitemplate

I am using the github.com/gin-contrib/multitemplate plugin as I need to use multiple templates, and it's recommended in the docs to use that. I am assuming that it's working as intended.

Environment

  • go version: go version go1.21.12 linux/amd64
  • gin version (or commit ref): v1.10.0
  • gin multitemplate: v1.0.1
  • operating system: Fedora Linux 40

Comment From: RedCrazyGhost

Although Conetxt.Keys and gin.H are both map[string]any, Keys are only used during the lifetime of the request and should not be exported as a result. gin.H is a specific output structure with multi-type support.

I suggest you use the code below to process the results and do something with the output

r.GET("/", func(ctx *gin.Context) {
   var mergeData gin.H
   for k, v := range ctx.Keys {
      mergedData[k] = v  // Process merge data
   }
   ctx.HTML(http.StatusOK, "index.html", mergeData)
})

Comment From: Yiannis128

Maybe it would be worth updating the documentation to state that, since my first impression was that it was a way of setting messages to be sent from the middleware to the endpoint.