138 lines
3.5 KiB
Go
138 lines
3.5 KiB
Go
// library github.com/CloudyKit/jet
|
|
package echojet
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
"reflect"
|
|
"sync"
|
|
|
|
"github.com/CloudyKit/jet/v3"
|
|
"github.com/labstack/echo/v4"
|
|
)
|
|
|
|
// RenderOptions is used to configure the renderer.
|
|
type RenderOptions struct {
|
|
TemplateDir string
|
|
ContentType string
|
|
VarMap *VarMapMx
|
|
}
|
|
|
|
// JetRender is a custom Gin template renderer using Pongo2.
|
|
type JetRender struct {
|
|
Options *RenderOptions
|
|
JetSet *jet.Set
|
|
}
|
|
|
|
// New creates a new JetRender instance with custom Options.
|
|
func New(options RenderOptions) *JetRender {
|
|
set := jet.NewHTMLSet(options.TemplateDir)
|
|
return &JetRender{
|
|
Options: &options,
|
|
JetSet: set,
|
|
}
|
|
}
|
|
|
|
// Default creates a JetRender instance with default options.
|
|
func Default() (jr *JetRender) {
|
|
jr = New(RenderOptions{
|
|
TemplateDir: "templates",
|
|
ContentType: "text/html; charset=utf-8",
|
|
// ContentType: "text/html",
|
|
VarMap: NewVarMapMx(),
|
|
})
|
|
jr.JetSet.SetDevelopmentMode(true)
|
|
return
|
|
}
|
|
|
|
// Render should render the template to the response.
|
|
func (p *JetRender) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
|
|
template, err := p.JetSet.GetTemplate(name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// p.Options.VarMap["urlfor"] = reflect.ValueOf(jet.Func(func(a jet.Arguments) reflect.Value {
|
|
// a.RequireNumOfArguments("urlfor", 1, -1)
|
|
// args := make([]interface{}, a.NumOfArguments())
|
|
// for i := 0; i < a.NumOfArguments(); i++ {
|
|
// args[i] = a.Get(i).Interface()
|
|
// }
|
|
// return reflect.ValueOf(c.Echo().Reverse(args[0].(string), args[1:]...))
|
|
// }))
|
|
|
|
// p.WriteContentType(w)
|
|
return template.Execute(w, p.Options.VarMap.GetVarMap(), data)
|
|
}
|
|
|
|
// WriteContentType should add the Content-Type header to the response
|
|
// when not set yet.
|
|
func (p *JetRender) WriteContentType(w io.Writer) {
|
|
if rw, ok := w.(http.ResponseWriter); ok {
|
|
header := rw.Header()
|
|
if val := header["Content-Type"]; len(val) == 0 {
|
|
// header["Content-Type"] = []string{p.Options.ContentType}
|
|
header.Set("Content-Type", p.Options.ContentType)
|
|
}
|
|
}
|
|
}
|
|
|
|
// VarMapMx defines a mutex-protected jet.VarMap that's usable concurrently.
|
|
type VarMapMx struct {
|
|
mx sync.RWMutex
|
|
varMap jet.VarMap
|
|
}
|
|
|
|
// NewVarMapMx returns an initialized VarMapMx instance that is ready to be used.
|
|
func NewVarMapMx() *VarMapMx {
|
|
return &VarMapMx{varMap: jet.VarMap{}}
|
|
}
|
|
|
|
// Get returns the value for a key in the embedded jet.VarMap.
|
|
// The returned reflect.Value is not valid if the key does not exist.
|
|
func (scope *VarMapMx) Get(name string) reflect.Value {
|
|
v, _ := scope.Lookup(name)
|
|
return v
|
|
}
|
|
|
|
// Lookup returns the value for a key in the embedded jet.VarMap
|
|
// as well as whether the key was found or not.
|
|
func (scope *VarMapMx) Lookup(name string) (reflect.Value, bool) {
|
|
scope.mx.RLock()
|
|
defer scope.mx.RUnlock()
|
|
v, ok := scope.varMap[name]
|
|
return v, ok
|
|
}
|
|
|
|
// Set adds the key value pair in the embedded jet.VarMap.
|
|
func (scope *VarMapMx) Set(name string, v interface{}) *VarMapMx {
|
|
scope.mx.Lock()
|
|
defer scope.mx.Unlock()
|
|
|
|
scope.varMap.Set(name, v)
|
|
return scope
|
|
}
|
|
|
|
// SetFunc adds a jet.Func to the embedded jet.VarMap.
|
|
func (scope *VarMapMx) SetFunc(name string, v jet.Func) *VarMapMx {
|
|
scope.mx.Lock()
|
|
defer scope.mx.Unlock()
|
|
|
|
scope.varMap.Set(name, v)
|
|
return scope
|
|
}
|
|
|
|
// SetWriter adds a jet.SafeWriter to the embedded jet.VarMap.
|
|
func (scope *VarMapMx) SetWriter(name string, v jet.SafeWriter) *VarMapMx {
|
|
scope.mx.Lock()
|
|
defer scope.mx.Unlock()
|
|
|
|
scope.varMap.Set(name, v)
|
|
return scope
|
|
}
|
|
|
|
// GetVarMap returns the embedded jet.VarMap for use in template executions.
|
|
func (scope *VarMapMx) GetVarMap() jet.VarMap {
|
|
return scope.varMap
|
|
}
|