2025-03-28 08:49:33 +01:00
|
|
|
package web
|
2025-03-27 09:19:08 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"github.com/flosch/pongo2/v6"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
|
|
"io"
|
|
|
|
"io/fs"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Renderer struct {
|
|
|
|
fs fs.FS
|
|
|
|
templates *pongo2.TemplateSet
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewRenderer creates a new Renderer struct.
|
|
|
|
func NewRenderer(fs fs.FS) *Renderer {
|
|
|
|
|
|
|
|
r := &Renderer{
|
|
|
|
fs: fs,
|
|
|
|
}
|
|
|
|
|
|
|
|
templates := pongo2.NewSet("templates", r)
|
|
|
|
r.templates = templates
|
|
|
|
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
// Abs returns absolute path to file requested.
|
|
|
|
// Search path is configured in AddDirectory method.
|
|
|
|
// And default directory is "./templates".
|
|
|
|
func (p *Renderer) Abs(base, name string) string {
|
|
|
|
return name
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get reads the path's content from your local filesystem.
|
|
|
|
func (p *Renderer) Get(path string) (io.Reader, error) {
|
|
|
|
|
|
|
|
f, err := p.fs.Open(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
data, err := io.ReadAll(f)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return bytes.NewReader(data), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// RegisterTag registers a custom tag.
|
|
|
|
// It calls pongo2.RegisterTag method.
|
|
|
|
func (p *Renderer) RegisterTag(name string, parserFunc pongo2.TagParser) {
|
|
|
|
pongo2.RegisterTag(name, parserFunc)
|
|
|
|
}
|
|
|
|
|
|
|
|
// RegisterFilter registers a custom filter.
|
|
|
|
// It calls pongo2.RegisterFilter method.
|
|
|
|
func (p *Renderer) RegisterFilter(name string, fn pongo2.FilterFunction) {
|
|
|
|
pongo2.RegisterFilter(name, fn)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetDebug sets debug mode to the template set.
|
|
|
|
// See pongo2.TemplateSet.Debug for more information.
|
|
|
|
func (p *Renderer) SetDebug(v bool) {
|
|
|
|
p.templates.Debug = v
|
|
|
|
}
|
|
|
|
|
|
|
|
// Render renders the view.
|
|
|
|
// Many other times, this is called in your echo handler functions.
|
|
|
|
func (p *Renderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
|
|
|
|
tmpl, err := p.templates.FromCache(name)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if tmpl == nil {
|
|
|
|
return fmt.Errorf("template '%s' not found", name)
|
|
|
|
}
|
|
|
|
d, ok := data.(map[string]interface{})
|
|
|
|
if !ok {
|
|
|
|
return errors.New("Incorrect data format. Should be map[string]interface{}")
|
|
|
|
}
|
|
|
|
|
|
|
|
return tmpl.ExecuteWriter(d, w)
|
|
|
|
}
|