template icon indicating copy to clipboard operation
template copied to clipboard

How to call url by url name

Open alwismt opened this issue 3 years ago • 1 comments

I have below route my project with name now i wanna call them inside templates

func ProductRoutes(a *fiber.App) {
	pc := controllers.ProductController{}
	// admin route
	route := a.Group("/admin/product")

	// add auth middleware to dashboard group
	route.Use(middleware.AuthProtected)

	route.Get("/", pc.Index).Name("product_index")          // get all products
	route.Get("/add", pc.Add).Name("product_add")           // add new product form
	route.Post("/", pc.Insert).Name("product_insert")       // add new product to database
	route.Get("/:id", pc.Show).Name("product_show")         // get a product with an ID
	route.Put("/:id", pc.Update).Name("product_update")     // update a product with an ID
	route.Delete("/:id", pc.Destroy).Name("product_delete") // delete a product
}

Below my controller

func (pc *ProductController) Index(c *fiber.Ctx) error {
	session.Get(c, "user_id")

	user := fiber.Map{
		"name":  session.Get(c, "name"),
		"email": session.Get(c, "email"),
	}
	search := c.Query("search")

	return c.Render("product/index", fiber.Map{
		"title":  "Selectify Admin",
		"admin":  user,
		"active": "products",
		"url":    c.OriginalURL(),
		"search": search,
	})
}

I wanna call product_index inside template

 <a href='{{ routePath "product_index" }}'>Products</a>

I tried few ways and search over google didn't found any answer, is there any way to do that?

alwismt avatar Jan 19 '23 05:01 alwismt

You can get route's URL with c.GetRouteURL(), however, *fiber.Ctx is not available in the template. I have gone the same path as you, and passed the *fiber.Ctx to template with a middleware:

First, this is how I create my fiber.App:

app := fiber.New(fiber.Config{
	...
	PassLocalsToViews: true,
})

See https://docs.gofiber.io/api/fiber#config for docs.

Then I have a middleware that passes *fiber.Ctx to template via locals.

func New(c *fiber.Ctx) error {
	c.Locals("C", c)

	return c.Next()
}

With this in place, you can use {{.C.GetRouteURL "template_name" nil}} in your template.

If your routes has parameters in them, you will need to create a template function that will enable you to create parameters map. I have something like this:

template.FuncMap{
	"map": func(args ...any) (fiber.Map, error) {
		if len(args)%2 != 0 {
			return nil, errors.New("number of params should be even")
		}

		m := fiber.Map{}

		for i := 0; i < len(args); i += 2 {
			m[args[i].(string)] = args[i+1]
		}

		return m, nil
	},
}

th0th avatar Jul 28 '23 13:07 th0th