Templates

Template Rendering

Context#Render(code int, name string, data interface{}) error renders a templatewith data and sends a text/html response with status code. Templates can be registered by setting Echo.Renderer, allowing us to use any template engine.

Example below shows how to use Go html/template:

  • Implement echo.Renderer interface
  1. type Template struct {
  2. templates *template.Template
  3. }
  4. func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
  5. return t.templates.ExecuteTemplate(w, name, data)
  6. }
  • Pre-compile templates

public/views/hello.html

  1. {{define "hello"}}Hello, {{.}}!{{end}}
  1. t := &Template{
  2. templates: template.Must(template.ParseGlob("public/views/*.html")),
  3. }
  • Register templates
  1. e := echo.New()
  2. e.Renderer = t
  3. e.GET("/hello", Hello)
  • Render a template inside your handler
  1. func Hello(c echo.Context) error {
  2. return c.Render(http.StatusOK, "hello", "World")
  3. }

Advanced - Calling Echo from templates

In certain situations it might be useful to generate URIs from the templates. In order to do so, you need to call Echo#Reverse from the templates itself. Golang’s html/template package is not the best suited for this job, but this can be done in two ways: by providing a common method on all objects passed to templates or by passing map[string]interface{} and augmenting this object in the custom renderer. Given the flexibility of the latter approach, here is a sample program:

template.html

  1. <html>
  2. <body>
  3. <h1>Hello {{index . "name"}}</h1>
  4. <p>{{ with $x := index . "reverse" }}
  5. {{ call $x "foobar" }} &lt;-- this will call the $x with parameter "foobar"
  6. {{ end }}
  7. </p>
  8. </body>
  9. </html>

server.go

  1. package main
  2. import (
  3. "html/template"
  4. "io"
  5. "net/http"
  6. "github.com/labstack/echo"
  7. )
  8. // TemplateRenderer is a custom html/template renderer for Echo framework
  9. type TemplateRenderer struct {
  10. templates *template.Template
  11. }
  12. // Render renders a template document
  13. func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
  14. // Add global methods if data is a map
  15. if viewContext, isMap := data.(map[string]interface{}); isMap {
  16. viewContext["reverse"] = c.Echo().Reverse
  17. }
  18. return t.templates.ExecuteTemplate(w, name, data)
  19. }
  20. func main() {
  21. e := echo.New()
  22. renderer := &TemplateRenderer{
  23. templates: template.Must(template.ParseGlob("*.html")),
  24. }
  25. e.Renderer = renderer
  26. // Named route "foobar"
  27. e.GET("/something", func(c echo.Context) error {
  28. return c.Render(http.StatusOK, "something.html", map[string]interface{}{
  29. "name": "Dolly!",
  30. })
  31. }).Name = "foobar"
  32. e.Logger.Fatal(e.Start(":8000"))
  33. }