I am currently trying to use a-h/templ
and create a map of the template functions that generates so that I can create a Render
method.
With this templating library, you write a .templ
file which then generated Go code where those templates are rendered as functions which all return the templ.Component
type.
I am then trying to create a map of those functions and refer to them by a string so that another function can call them with just the name and then chain a method on to the returned templ.Component
but can't seem to get this working as the unknown parameters don't allow this.
I am wondering if this is even possible?
I have the following code:
base.templ
:
package templates
templ Hello(name string) {
<div>Hello, { name }</div>
}
templ Greeting(person string, num int) {
<div class="greeting">
@Hello(person)
</div>
<div>You are the { num }th person</div>
}
templ Goodbye() {
<div>Goodbye</div>
}
renderer.go
:
package utils
import (
"io"
"github.com/a-h/templ"
"github.com/labstack/echo/v4"
)
type Template struct {
Components *map[string]func(...any) templ.Component
}
func (t *Template) GetComponents() (map[string]func(...any) templ.Component, bool) {
if t == nil {
return nil, false
}
return *t.Components, true
}
func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
comp, exists := t.GetComponents()
if !exists {
return nil
}
return comp[name](data).Render(c.Request().Context(), w)
}
(I know the comp(data)
won't work here - this is something to be changed but not the current issue I'm asking for help)
main.go
:
package main
import (
"net/http"
"github.com/a-h/templ"
"github.com/labstack/echo/v4"
templates "project-setup.com/web/components/layout"
"project-setup.com/web/utils"
)
func main() {
e := echo.New()
comps := make(map[string]func(...any) templ.Component)
t := templates.Greeting
comps["greeting"] = &t
e.GET("/hello", func(c echo.Context) error {
e.Renderer = &utils.Template{
Components: &comps,
}
return c.Render(200, "", "This guy")
})
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, Root!")
})
e.Logger.Fatal(e.Start(":1323"))
}
This gives me an error for the line comps["greeting"] = &t
in main.go
saying cannot use &t (value of type *func(person string, num int) templ.Component) as func(...any) templ.Component value in assignment compiler(IncompatibleAssign)
.
I understand that they are technically different method signatures hence the issue, but is there no way to achieve what I'm trying to do?
echo
has a Renderer you can assign to serve templated responses but no way to provide a function as the template rather than a string.