gogo-gin

Pass common data to HTML templates using gin middleware (Golang)


I'm building a blog using Golang's gin framework. In my blog, I have a Categories drop-down menu in the navbar that appears in all pages.

Currently I'm passing the categories in each control:

categories := db.GetCategories()

c.HTML(200, "page.html", gin.H{"categories": categories})

Is there a way to pass these data from a middleware to all templates without having to do that explicitly in the final handler?


Solution

  • Yes, you can achieve this by using a middleware function in Gin. Middleware functions in Gin are handlers that execute before or after the main handler, allowing you to perform operations such as logging, authentication, or in your case, fetching data to be used across multiple routes or templates.

    You can create a middleware function that fetches the categories from the database and then stores them in the context. This way, the categories will be available to all handlers without explicitly passing them in each handler.

    Here's an example of how you can do it:

    func CategoriesMiddleware() gin.HandlerFunc {
        return func(c *gin.Context) {
            categories := db.GetCategories()
            c.Set("categories", categories)
            c.Next()
        }
    }
    
    func main() {
        r := gin.Default()
    
        // Use the middleware for all routes
        r.Use(CategoriesMiddleware())
    
        r.GET("/", func(c *gin.Context) {
            // Access categories from context
            categories := c.MustGet("categories").([]string)
            // Render your template
            c.HTML(200, "page.html", gin.H{"categories": categories})
        })
        r.Run(":8080")
    }