Skip to content

Instantly share code, notes, and snippets.

@robvdl
Last active March 7, 2024 19:43
Show Gist options
  • Save robvdl/04dba3945e7949727085a37f53190124 to your computer and use it in GitHub Desktop.
Save robvdl/04dba3945e7949727085a37f53190124 to your computer and use it in GitHub Desktop.
Setting up Pongo2 with Echo v4
package web
import (
"io"
"github.com/flosch/pongo2/v6"
"github.com/labstack/echo/v4"
"github.com/spf13/viper"
)
// RenderOptions is used to configure the renderer.
type RenderOptions struct {
TemplateDir string
TemplateSet *pongo2.TemplateSet
ContentType string
}
// Pongo2Render is a custom Echo template renderer using Pongo2.
type Pongo2Render struct {
Options *RenderOptions
}
// NewRender creates a new Pongo2Render instance with custom Options.
func NewRender(options RenderOptions) (*Pongo2Render, error) {
// If TemplateSet is nil construct a new TemplateSet for TemplateDir.
if options.TemplateSet == nil {
loader, err := pongo2.NewLocalFileSystemLoader(options.TemplateDir)
if err != nil {
return nil, err
}
options.TemplateSet = pongo2.NewSet(options.TemplateDir, loader)
options.TemplateSet.Debug = viper.GetBool("debug")
}
render := &Pongo2Render{Options: &options}
return render, nil
}
// DefaultRender creates a Pongo2Render instance with default options.
func DefaultRender() (*Pongo2Render, error) {
return NewRender(RenderOptions{
TemplateDir: viper.GetString("template_dir"),
TemplateSet: nil,
ContentType: echo.MIMETextHTMLCharsetUTF8,
})
}
// Render is an interface function that renders a Pongo2 template as an HTML response.
func (p *Pongo2Render) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
template, err := p.Options.TemplateSet.FromCache(name)
if err != nil {
return err
}
c.Response().Header().Set(echo.HeaderContentType, p.Options.ContentType)
return template.ExecuteWriter(data.(pongo2.Context), w)
}
@robvdl
Copy link
Author

robvdl commented Jul 3, 2023

Also this probably should come with a "how to use", here goes:

e := echo.New()
e.Debug = viper.GetBool("debug")

// Setup the Pongo2 renderer
render, err := DefaultRender()
if err != nil {
	// handle or return error (e.g. template dir does not exist could return an error)
}
e.Renderer = render

// Start Echo
e.Logger.Fatal(e.Start(":8080"))

@robvdl
Copy link
Author

robvdl commented Jul 4, 2023

The reason I am using TemplateSet actually originated in my pongo2gin repo on Gitlab (gitlab.com/go-box/pongo2gin), a contributor needed this and added support for template sets. I since cleaned it up, refactored it, and translated the code to use Echo instead of Gin.

You may notice it automatically creates a TemplateSet based on the template dir if TemplateSet was nil. Otherwise it will use the TemplateSet you pass in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment