90 lines
2.0 KiB
Go
90 lines
2.0 KiB
Go
|
package html
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"html/template"
|
||
|
"net/http"
|
||
|
"path/filepath"
|
||
|
|
||
|
"github.com/oxtoacart/bpool"
|
||
|
)
|
||
|
|
||
|
// TemplateService is a template/html based templating service
|
||
|
type TemplateService struct {
|
||
|
templates map[string]*template.Template
|
||
|
pool *bpool.BufferPool
|
||
|
helpers template.FuncMap
|
||
|
}
|
||
|
|
||
|
// LoadTemplates loads the templates used by the service
|
||
|
func (t *TemplateService) LoadTemplates(templatesDir string) error {
|
||
|
|
||
|
layouts, err := filepath.Glob(filepath.Join(templatesDir, "layouts", "*.tmpl"))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
blocks, err := filepath.Glob(filepath.Join(templatesDir, "blocks", "*.tmpl"))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// Generate our templates map from our layouts/ and blocks/ directories
|
||
|
for _, layout := range layouts {
|
||
|
|
||
|
var err error
|
||
|
files := append(blocks, layout)
|
||
|
|
||
|
tmpl := template.New("")
|
||
|
tmpl.Funcs(t.helpers)
|
||
|
|
||
|
tmpl, err = tmpl.ParseFiles(files...)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
t.templates[filepath.Base(layout)] = tmpl
|
||
|
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
|
||
|
}
|
||
|
|
||
|
// RenderPage renders a template to the given http.ResponseWriter
|
||
|
func (t *TemplateService) RenderPage(w http.ResponseWriter, templateName string, data interface{}) error {
|
||
|
|
||
|
// Ensure the template exists in the map.
|
||
|
tmpl, ok := t.templates[templateName]
|
||
|
if !ok {
|
||
|
return fmt.Errorf("the template '%s' does not exist", templateName)
|
||
|
}
|
||
|
|
||
|
// Create a buffer to temporarily write to and check if any errors were encountered.
|
||
|
buf := t.pool.Get()
|
||
|
defer t.pool.Put(buf)
|
||
|
|
||
|
if err := tmpl.ExecuteTemplate(buf, templateName, data); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// Set the header and write the buffer to the http.ResponseWriter
|
||
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||
|
_, err := buf.WriteTo(w)
|
||
|
return err
|
||
|
|
||
|
}
|
||
|
|
||
|
// NewTemplateService returns a new Service
|
||
|
func NewTemplateService(funcs ...OptionFunc) *TemplateService {
|
||
|
options := defaultOptions()
|
||
|
for _, f := range funcs {
|
||
|
f(options)
|
||
|
}
|
||
|
return &TemplateService{
|
||
|
templates: make(map[string]*template.Template),
|
||
|
pool: bpool.NewBufferPool(options.PoolSize),
|
||
|
helpers: options.Helpers,
|
||
|
}
|
||
|
}
|