gofiber / template

🧬 Template engine middleware for Fiber
https://docs.gofiber.io/guide/templates
MIT License
265 stars 52 forks source link

Handlebars: Helper already exists #146

Closed kde99 closed 2 years ago

kde99 commented 2 years ago

Hello everyone.

I am trying to add a helper function via AddFunc to the handlebars template engine, but it crashes whenever I use this helper (when loading the page from the browser). I am using GO1.17.2 and the lastest packages (just downloaded them to test).

This is a minimal example case where it still crashes:

package main

import (
    "github.com/gofiber/template/handlebars"
    "github.com/gofiber/fiber/v2"
  "math"
  "log"
)

func main() {
    templateEngine := handlebars.New("./templates", ".html")
    templateEngine.Reload(true)
    templateEngine.Debug(true) // prints template names when parsed
    templateEngine.AddFunc("getLevelFromXP", func(xp uint) uint {
        return uint((-87.5+math.Sqrt(87.5*87.5+50.0*float64(xp)))/25)
    })

    app := fiber.New(fiber.Config {
        Views: templateEngine,
    })

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

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

The template simply contains {{getLevelFromXP 1200}} but it is not parsed because even when the index template is missing I still get the crash.

panic: Helper already registered: getLevelFromXP

goroutine 34 [running]:
github.com/aymerick/raymond.RegisterHelper({0xf84a9f, 0xe}, {0xef9b80, 0xfa9d00})
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/aymerick/raymond@v2.0.2+incompatible/helper.go:43 +0x2a5
github.com/aymerick/raymond.RegisterHelpers(0xf90322)
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/aymerick/raymond@v2.0.2+incompatible/helper.go:55 +0x85
github.com/gofiber/template/handlebars.(*Engine).Load(0xc0003a36c0)
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/template@v1.6.19/handlebars/handlebars.go:112 +0xce
github.com/gofiber/template/handlebars.(*Engine).Render(0xc0003a36c0, {0x104f7c0, 0xc0000b5248}, {0xf828be, 0xa}, {0xf167c0, 0xc0004a0840}, {0x0, 0x0, 0x0})
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/template@v1.6.19/handlebars/handlebars.go:184 +0x77
github.com/gofiber/fiber/v2.(*Ctx).Render(0xc0004b6000, {0xf828be, 0xa}, {0xf167c0, 0xc0004a0840}, {0x0, 0x0, 0x0})
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/v2@v2.22.0/ctx.go:1004 +0x1af
main.main.func1(0xf0c260)
    D:/projects/minimal/main.go:53 +0x245
github.com/gofiber/fiber/v2.(*App).next(0xc0002d6b60, 0xc0004b6000)
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/v2@v2.22.0/router.go:127 +0x1d8
github.com/gofiber/fiber/v2.(*Ctx).Next(0x0)
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/v2@v2.22.0/ctx.go:747 +0x53
github.com/gofiber/fiber/v2/middleware/logger.New.func2(0xc0004b6000)
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/v2@v2.22.0/middleware/logger/logger.go:159 +0x1f7
github.com/gofiber/fiber/v2.(*App).next(0xc0002d6b60, 0xc0004b6000)
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/v2@v2.22.0/router.go:127 +0x1d8
github.com/gofiber/fiber/v2.(*App).handler(0xc0002d6b60, 0x8ea577)
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/v2@v2.22.0/router.go:155 +0xe5
github.com/valyala/fasthttp.(*Server).serveConn(0xc0000c4000, {0x1062350, 0xc000408008})
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/valyala/fasthttp@v1.31.0/server.go:2278 +0x122d
github.com/valyala/fasthttp.(*workerPool).workerFunc(0xc0000dc3c0, 0xc00040e060)
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/valyala/fasthttp@v1.31.0/workerpool.go:223 +0xa9
github.com/valyala/fasthttp.(*workerPool).getCh.func1()
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/valyala/fasthttp@v1.31.0/workerpool.go:195 +0x38
created by github.com/valyala/fasthttp.(*workerPool).getCh
    D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/valyala/fasthttp@v1.31.0/workerpool.go:194 +0x1b5

Any help is appreciated.

kde99 commented 2 years ago

Ok so found the problem: if you have Reload(true) then whenever you reload the templates this library tries to register the helpers using raymond.RegisterHelpers (handlebars.go line 112) that function tries to register the helpers using it's own RegisterHelper(name, helper) function. And this function checks if the given helper has been registered or not. (Doing a git blame on raymond and it appears that code has been there for like 7 years so probably no one needed this so far?) The fix is trivial though. Either

  1. Only register those helpers that are currently not register (which is not what we probably want since this repo says you can override default helpers)
  2. Override the ones (like delete and register again) that we want to be ours
  3. Catch error (probably not ideal since then we won't register all)

Edit: apparently 1 and 2 are not possible because raymond doesn't export a HasHelper/RemoveHelper or anything similar, also the map containing the helpers is not accessible.

Remove helper has been added by the latest 2018 commit I guess that repo died since then I will be going with a different template engine and closing this.

mmgfrcs commented 2 years ago

I just encountered this problem, and it hasn't been fixed Probably going to fork and fix it myself