gofiber / fiber

⚡️ Express inspired web framework written in Go
https://gofiber.io
MIT License
33.12k stars 1.63k forks source link

🤗 [Question]: How can use named routes in the template #2093

Closed mybigman closed 2 years ago

mybigman commented 2 years ago

Question Description

All my GET endpoints use named routes. How I can I utilize this inside HTML templates?

I would like not having to hardcode these if possible?

Code Snippet (optional)

// endpoint
route.Get("/upload", controllers.ShowUpload).Name("upload")

// template eg:
<a href="{{ to('upload') }}">action</a>

Checklist:

ReneWerner87 commented 2 years ago

inject the router (the app or group) in the template system and use this method https://docs.gofiber.io/api/app#getroute

mybigman commented 2 years ago

@ReneWerner87 thanks, however I am not seeing how since the AddFunc has to come before the app

I dont really want to have to inject the app on every endpoint.

engine := html.New("./views", ".html")

engine.AddFunc("test", func(r string) string {
    // need app here
    return app.GetRoute(r).Name
})

app := fiber.New(fiber.Config{
    Views:             engine,
    ViewsLayout:       "layouts/base",
    BodyLimit:         20 * 1024 * 1024, // 20MB limit
})
ReneWerner87 commented 2 years ago

Can try to provide an example later

ReneWerner87 commented 1 year ago

Solution 1:

func main() {
    engine := html.New("./assets", ".html")
    engine.AddFunc("getRoute", func(a *fiber.App, r string) string {
        return a.GetRoute(r).Path
    })

    app := fiber.New(fiber.Config{
        Views:     engine,
        BodyLimit: 20 * 1024 * 1024, // 20MB limit
    })
    // register the app for the view engine
    app.Use(func(ctx *fiber.Ctx) error {
        ctx.Bind(fiber.Map{"app": app})
        return ctx.Next()
    })

    app.Get("/test", func(ctx *fiber.Ctx) error {
        return ctx.Render("test", fiber.Map{
            "Title": "Hello, <b>World</b>!",
        })
    }).Name("testRoute")
}
    <h1>{{.Title}}</h1>
    <div>{{ getRoute .app "testRoute" }}</div>

maybe we should do the initialization of the template system only when listing just before we issue the start message to allow for better addition of the app

we will consider this for version 3

mybigman commented 1 year ago

@ReneWerner87 thanks mate much appreciated... I will work on that tonight. I like the sound of your proposed solution.

foreverlz1111 commented 1 year ago

@ReneWerner87 Yes,template could be initiated on first load,then we“Render”some new data to update the page. On V2: app.Get("/", responder.InitDir) app.Post("/u", responder.UpdateDir) If my template in "/" and I want to get new DirList after refresh the web,but the update was always overwrited by the first Get. @ReneWerner87


Solution 1:

func main() {
  engine := html.New("./assets", ".html")
  engine.AddFunc("getRoute", func(a *fiber.App, r string) string {
      return a.GetRoute(r).Path
  })

  app := fiber.New(fiber.Config{
      Views:     engine,
      BodyLimit: 20 * 1024 * 1024, // 20MB limit
  })
  // register the app for the view engine
  app.Use(func(ctx *fiber.Ctx) error {
      ctx.Bind(fiber.Map{"app": app})
      return ctx.Next()
  })

  app.Get("/test", func(ctx *fiber.Ctx) error {
      return ctx.Render("test", fiber.Map{
          "Title": "Hello, <b>World</b>!",
      })
  }).Name("testRoute")
}
    <h1>{{.Title}}</h1>
    <div>{{ getRoute .app "testRoute" }}</div>

maybe we should do the initialization of the template system only when listing just before we issue the start message to allow for better addition of the app

we will consider this for version 3