101 lines
1.7 KiB
Go
101 lines
1.7 KiB
Go
package template
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
)
|
|
|
|
var Cache *TemplateCache
|
|
|
|
type TemplateCache struct {
|
|
mu sync.RWMutex
|
|
templates map[string]*Template
|
|
basePath string
|
|
}
|
|
|
|
func NewCache(basePath string) *TemplateCache {
|
|
if basePath == "" {
|
|
exe, err := os.Executable()
|
|
if err != nil {
|
|
basePath = "."
|
|
} else {
|
|
basePath = filepath.Dir(exe)
|
|
}
|
|
}
|
|
|
|
return &TemplateCache{
|
|
templates: make(map[string]*Template),
|
|
basePath: basePath,
|
|
}
|
|
}
|
|
|
|
func InitializeCache(basePath string) {
|
|
Cache = NewCache(basePath)
|
|
}
|
|
|
|
func (c *TemplateCache) Load(name string) (*Template, error) {
|
|
c.mu.RLock()
|
|
tmpl, exists := c.templates[name]
|
|
c.mu.RUnlock()
|
|
|
|
if exists {
|
|
if err := c.checkAndReload(tmpl); err != nil {
|
|
return nil, err
|
|
}
|
|
return tmpl, nil
|
|
}
|
|
|
|
return c.loadFromFile(name)
|
|
}
|
|
|
|
func (c *TemplateCache) loadFromFile(name string) (*Template, error) {
|
|
filePath := filepath.Join(c.basePath, "templates", name)
|
|
|
|
info, err := os.Stat(filePath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("template file not found: %s", name)
|
|
}
|
|
|
|
content, err := os.ReadFile(filePath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read template: %w", err)
|
|
}
|
|
|
|
tmpl := &Template{
|
|
name: name,
|
|
content: string(content),
|
|
modTime: info.ModTime(),
|
|
filePath: filePath,
|
|
cache: c,
|
|
}
|
|
|
|
c.mu.Lock()
|
|
c.templates[name] = tmpl
|
|
c.mu.Unlock()
|
|
|
|
return tmpl, nil
|
|
}
|
|
|
|
func (c *TemplateCache) checkAndReload(tmpl *Template) error {
|
|
info, err := os.Stat(tmpl.filePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if info.ModTime().After(tmpl.modTime) {
|
|
content, err := os.ReadFile(tmpl.filePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
c.mu.Lock()
|
|
tmpl.content = string(content)
|
|
tmpl.modTime = info.ModTime()
|
|
c.mu.Unlock()
|
|
}
|
|
|
|
return nil
|
|
}
|