Search code examples
gogo-echo

Golang Echo Labstack How to Call a Function / Method in a Template View


I am building a front end website with Golang Echo Labstack framework, and I want to call some custom functions in my template view. How do I do this with Echo?

For example, I am able to do this with Gin

func main() {
    r := gin.Default()
    r.SetFuncMap(template.FuncMap{
        // Add my custom functions
        "AddTS": util.AddTS,
        "Encrypt": util.EncryptGeneral,
        "CombineVariable": util.CombineVariable,
    })
    
    r.Static("/static", "./static")
    r.LoadHTMLFiles("static/*/*") //  load the static path
    r.LoadHTMLGlob("templates/*/*")

    route.Routes(r)
    r.Run()
}

and in my template view, I could simply call any of my custom functions like this.

range {{ .Data }}
    <div>
        {{ .data_value | AddTS }}
        {{ .data_value | OtherCustomFunction }}
    </div>
{{ end }}

But I can't seem to find a similar methods in Echo, how do I implement a global function that I can use in my template views?

Here is my current Echo file

type TemplateRenderer struct {
    templates *template.Template
}

func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {

    // Add global methods if data is a map
    if viewContext, isMap := data.(map[string]interface{}); isMap {
        viewContext["reverse"] = c.Echo().Reverse
    }

    return t.templates.ExecuteTemplate(w, name, data)
}

func main() {
    e := echo.New()

    renderer := &TemplateRenderer{
        templates: template.Must(template.ParseGlob("templates/*/*.tmpl")),
    }
    e.Renderer = renderer

    e.Static("/static", "static")
    
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())
    e.Logger.Fatal(e.Start(":8183"))
}

*For some reasons, I cannot use Gin for this project and must only use Echo.

Thanks a lot.


Solution

  • You can easily implement your own renderer, as explained in the guide here, and use Go's own html/template package to manage the templates:

    import (
        "html/template"
        // ...
    )
    
    type TemplateRenderer struct {
        templates *template.Template
    }
    
    func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
    
        // Add global methods if data is a map
        if viewContext, isMap := data.(map[string]interface{}); isMap {
            viewContext["reverse"] = c.Echo().Reverse
        }
    
        return t.templates.ExecuteTemplate(w, name, data)
    }
    

    And to give the templates access to custom functions you can use the Funcs method like so:

    renderer := &TemplateRenderer{
        templates: template.Must(template.New("t").Funcs(template.FuncMap{
            "AddTS":           util.AddTS,
            "Encrypt":         util.EncryptGeneral,
            "CombineVariable": util.CombineVariable,
        }).ParseGlob("templates/*/*.tmpl")),
    }