102 lines
2.1 KiB
Go
102 lines
2.1 KiB
Go
// Filename: internal/pongo/renderer.go
|
|
|
|
package pongo
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/flosch/pongo2/v6"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/gin-gonic/gin/render"
|
|
)
|
|
|
|
type Renderer struct {
|
|
Context pongo2.Context
|
|
tplSet *pongo2.TemplateSet
|
|
}
|
|
|
|
func New(directory string, isDebug bool) *Renderer {
|
|
loader := pongo2.MustNewLocalFileSystemLoader(directory)
|
|
tplSet := pongo2.NewSet("gin-pongo-templates", loader)
|
|
tplSet.Debug = isDebug
|
|
return &Renderer{Context: make(pongo2.Context), tplSet: tplSet}
|
|
}
|
|
|
|
// Instance returns a new render.HTML instance for a single request.
|
|
func (p *Renderer) Instance(name string, data interface{}) render.Render {
|
|
var glob pongo2.Context
|
|
if p.Context != nil {
|
|
glob = p.Context
|
|
}
|
|
|
|
var context pongo2.Context
|
|
if data != nil {
|
|
if ginContext, ok := data.(gin.H); ok {
|
|
context = pongo2.Context(ginContext)
|
|
} else if pongoContext, ok := data.(pongo2.Context); ok {
|
|
context = pongoContext
|
|
} else if m, ok := data.(map[string]interface{}); ok {
|
|
context = m
|
|
} else {
|
|
context = make(pongo2.Context)
|
|
}
|
|
} else {
|
|
context = make(pongo2.Context)
|
|
}
|
|
|
|
for k, v := range glob {
|
|
if _, ok := context[k]; !ok {
|
|
context[k] = v
|
|
}
|
|
}
|
|
|
|
tpl, err := p.tplSet.FromCache(name)
|
|
if err != nil {
|
|
panic(fmt.Sprintf("Failed to load template '%s': %v", name, err))
|
|
}
|
|
|
|
return &HTML{
|
|
p: p,
|
|
Template: tpl,
|
|
Name: name,
|
|
Data: context,
|
|
}
|
|
}
|
|
|
|
type HTML struct {
|
|
p *Renderer
|
|
Template *pongo2.Template
|
|
Name string
|
|
Data pongo2.Context
|
|
}
|
|
|
|
func (h *HTML) Render(w http.ResponseWriter) error {
|
|
h.WriteContentType(w)
|
|
bytes, err := h.Template.ExecuteBytes(h.Data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = w.Write(bytes)
|
|
return err
|
|
}
|
|
|
|
func (h *HTML) WriteContentType(w http.ResponseWriter) {
|
|
header := w.Header()
|
|
if val := header["Content-Type"]; len(val) == 0 {
|
|
header["Content-Type"] = []string{"text/html; charset=utf-8"}
|
|
}
|
|
}
|
|
|
|
func C(ctx *gin.Context) pongo2.Context {
|
|
p, exists := ctx.Get("pongo2")
|
|
if exists {
|
|
if pCtx, ok := p.(pongo2.Context); ok {
|
|
return pCtx
|
|
}
|
|
}
|
|
pCtx := make(pongo2.Context)
|
|
ctx.Set("pongo2", pCtx)
|
|
return pCtx
|
|
}
|