Golang Gin Middleware pass Data to Template

Issue

Hi currently i am doing a little project and i have question.

Is there a way to pass Data to a template from a Middleware?

For Example:

func CheckAuth(c *gin.Context) { //This Middleware gets the user from the session and passes it to the template 
session := sessions.Default(c)
user := session.Get(userkey)

// Get if possible the user from the database with id = user
var account models.Account
if err := models.DB.Where("id = ?", user).First(&account).Error; err != nil {

    _ = 1
}
// pass the account into every temaplte

c.Next()

The reason is that i use the user in my layout and have to check his username or if he is just nil etc and doing the pass in every functions feels wrong?
I know Laravel has something like this.

I am using the c.HTML to display the html file

Thanks in advance!

Solution

You can use SetFuncMap or FuncMap to create custom functions on templates.

You must set it before calling LoadHTMLFiles or LoadHTMLGlob.

Middleware is for control value, ie: struct

This is the example

main.go

package main

import (
    "html/template"
    "log"
    "strconv"

    "github.com/gin-gonic/gin"
)

type User struct {
    Username string

    Age int
}

func setUser(u *User) gin.HandlerFunc {
    return func(ctx *gin.Context) {
        // u.Age = 100
        // u.Username = "Default"
        if s, b := ctx.GetQuery("username"); b {
            u.Username = s
        }
        if s, b := ctx.GetQuery("age"); b {
            i, err := strconv.Atoi(s)
            if err != nil {
                panic(err.Error())
            }
            u.Age = i
        }
    }
}

var user = &User{"Default", 100}

func GetUsername() string {
    return user.Username
}

func GetAge() int {
    return user.Age
}

func main() {
    r := gin.New()

    r.SetFuncMap(template.FuncMap{
        "Username": GetUsername,
        "Age":      GetAge,
    })
    r.LoadHTMLGlob("*.tmpl")

    r.GET("/", setUser(user), func(ctx *gin.Context) {
        data := map[string]interface{}{
            "title": "Learning Golang Web",
            "name":  "Batman",
        }

        ctx.HTML(200, "index.tmpl", data)
    })

    log.Fatalln(r.Run())
}

index.tmpl

<!DOCTYPE html>
<html>
  <head>
    <title>{{.title}}</title>
  </head>
  <body>
    <p>Welcome {{.name}}</p>
    <p>Your Username is {{ Username }}</p>
    <p>Your Age is {{ Age }}</p>
  </body>
</html>

if you go to http://localhost:8080/?username=admin&age=50 it will show different display

Answered By – Rahmat Fathoni

Answer Checked By – Katrina (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.