package main
import (
"html/template"
"log"
"os"
"path/filepath"
"time"
"github.com/gin-gonic/gin"
)
var tm *TemplateManager
func init() {
tm = NewTemplateManager("templates", "base", "html")
}
type TemplateManager struct {
templates map[string]*template.Template
funcs template.FuncMap
base string
ext string
dir string
}
// NewTemplateManager initializes the manager and loads templates
func NewTemplateManager(dir string, base string, ext string) *TemplateManager {
tm := &TemplateManager{
templates: make(map[string]*template.Template),
funcs: template.FuncMap{
// Attach functions to the templates here
"fmtTime": func(t time.Time) string {
return t.Local().Format("2006-01-02 15:04") // Go’s reference time
},
"cmpTwo": func(a, b int) bool {
return a == b
},
},
base: base,
dir: dir,
ext: ext,
}
// Populate template manager
tm.LoadTemplates()
return tm
}
// LoadTemplates parses the base template with each view template in the directory
func (tm *TemplateManager) LoadTemplates() {
pattern := filepath.Join(tm.dir, "*."+tm.ext)
files, err := filepath.Glob(pattern)
if err != nil {
panic(err)
}
base := filepath.Join(tm.dir, tm.base+"."+tm.ext)
for _, file := range files {
if filepath.Base(file) == tm.base {
continue
}
name := stripAfterDot(filepath.Base(file))
// Parse base + view template together
tpl, err := template.New(name).
Funcs(tm.funcs).
ParseFiles(base, file)
if err != nil {
panic(err)
}
tm.templates[name] = tpl
}
}
// Render executes a template by name into the given context
func (tm *TemplateManager) Render(c *gin.Context, name string, data gin.H) error {
u := getSessionUser(c)
// Prefil the data for the render
data["CurrentUser"] = u
// Try to get information from current context that is filled from the session middleware
data["Form"], _ = c.Get("form")
data["Message"], _ = c.Get("mes")
tpl, ok := tm.templates[name]
if !ok {
return os.ErrNotExist
}
if err := tpl.ExecuteTemplate(c.Writer, tm.base, data); err != nil {
log.Println("template error:", err)
c.Status(500)
return err
}
return nil
}