bsky-app/bskyweb/cmd/bskyweb/renderer.go

83 lines
1.6 KiB
Go

package main
import (
"bytes"
"embed"
"errors"
"fmt"
"io"
"path/filepath"
"github.com/flosch/pongo2/v6"
"github.com/labstack/echo/v4"
)
type RendererLoader struct {
prefix string
fs *embed.FS
}
func NewRendererLoader(prefix string, fs *embed.FS) pongo2.TemplateLoader {
return &RendererLoader{
prefix: prefix,
fs: fs,
}
}
func (l *RendererLoader) Abs(_, name string) string {
// TODO: remove this workaround
// Figure out why this method is being called
// twice on template names resulting in a failure to resolve
// the template name.
if filepath.HasPrefix(name, l.prefix) {
return name
}
return filepath.Join(l.prefix, name)
}
func (l *RendererLoader) Get(path string) (io.Reader, error) {
b, err := l.fs.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("reading template %q failed: %w", path, err)
}
return bytes.NewReader(b), nil
}
type Renderer struct {
TemplateSet *pongo2.TemplateSet
Debug bool
}
func NewRenderer(prefix string, fs *embed.FS, debug bool) *Renderer {
return &Renderer{
TemplateSet: pongo2.NewSet(prefix, NewRendererLoader(prefix, fs)),
Debug: debug,
}
}
func (r Renderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
var ctx pongo2.Context
if data != nil {
var ok bool
ctx, ok = data.(pongo2.Context)
if !ok {
return errors.New("no pongo2.Context data was passed")
}
}
var t *pongo2.Template
var err error
if r.Debug {
t, err = pongo2.FromFile(name)
} else {
t, err = r.TemplateSet.FromFile(name)
}
if err != nil {
return err
}
return t.ExecuteWriter(ctx, w)
}