gofiber / fiber

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

🤗 [Question]: How to render templates from standard library embed? #1978

Closed SharkFourSix closed 2 years ago

SharkFourSix commented 2 years ago

Question Description

Almost all examples on this topic do not work the way I want and there aren't really similar examples anyway.

Please look at the code below

Code Snippet (optional)

package main

import (
"embed"
    "fmt"
    "net/http"

    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/fiber/v2/middleware/filesystem"
    "github.com/gofiber/fiber/v2/middleware/recover"
    "github.com/gofiber/template/django"
)

//go:embed resources/web/views
var views embed.FS

func main() {
  //tmplEngine := django.NewFileSystem(http.Dir("./resources/web/views"), ".html") // <-- This works fine

  // The following does not render templates. The engine returns an error saying it cannot find the template login. However, debug output shows that it is able to discover all embeded files
  tmplEngine := django.NewFileSystem(http.FS(views), ".html")
  tmplEngine.Debug(true)
  tmplEngine.Reload(true)

  app := fiber.New(fiber.Config{
    Views: tmplEngine,
    ErrorHandler: func(c *fiber.Ctx, err error) error {
        log.Error(err.Error())
        fmt.Println(err)
        return c.Render("error.html", fiber.Map{
            "Status": err.Error(),
            "Code":   500,
        })
    },
  })

  app.Use(recover.New())

  app.Get("/", func(c *fiber.Ctx) error {
      return c.Render("login", fiber.Map{})
  })

  log.Fatal(app.Listen(":3000"))
}

EDIT:

On further inispection, the following lines are causing the issue.

https://github.com/Fenny/template/blob/45e77be49336c1f95167b93962090bebd340e8fe/django/django.go#L23

Because this here (https://github.com/Fenny/template/blob/45e77be49336c1f95167b93962090bebd340e8fe/django/django.go#L45) we are able to set the directory explicitly, the following logic works when templates are loaded from disk: https://github.com/Fenny/template/blob/45e77be49336c1f95167b93962090bebd340e8fe/django/django.go#L142

However, using this method https://github.com/Fenny/template/blob/45e77be49336c1f95167b93962090bebd340e8fe/django/django.go#L57, this line fails because Engine.directory by default ends up being "/". The templates then get saved with full path, minus the "/", which means we have to pass the full path to the template ctx.Render("resources/web/views/index",...).

It's counterintuitive this way because we hare including even the base path.

Is there a way to expose Engine.directory when using django.NewFileSystem()?

Checklist:

SharkFourSix commented 2 years ago

FYI, this was addressed here https://github.com/gofiber/template/pull/187