Last active
March 7, 2024 19:43
-
-
Save robvdl/04dba3945e7949727085a37f53190124 to your computer and use it in GitHub Desktop.
Setting up Pongo2 with Echo v4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | |
| } |
Author
Author
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"))
Author
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
If e.Debug is true (were e is the Echo app), then it will not use a template cache. This is great for development as you can make changes to templates and not have to restart the app.
In production however, when e.Debug is false, it will use a template cache. In this mode, the first time a template is loaded from disk and compiled, it caches the compiled template. So any changes to the template on disk thereafter, requires restarting of the application as the app won't reload it. This is suitable for production but not development.