@ -3,6 +3,7 @@ package templates
import (
import (
"html/template"
"html/template"
"io"
"io"
"log"
"path"
"path"
"strings"
"strings"
@ -10,20 +11,23 @@ import (
"git.phc.dm.unipi.it/phc/website/util"
"git.phc.dm.unipi.it/phc/website/util"
)
)
// CachedTemplate holds a reference to the list of patterns to preload and a reference to the already parsed template
type CachedTemplate struct {
type CachedTemplate struct {
LoadPatterns [ ] string
Pre LoadTemplate Patterns [ ] string
cachedTmpl * template . Template
cachedTmpl * template . Template
}
}
// NewCacheTemplate creates a new template from a list of patterns a loads it
func NewCacheTemplate ( loadPatterns ... string ) * CachedTemplate {
func NewCacheTemplate ( loadPatterns ... string ) * CachedTemplate {
cachedTemplate := & CachedTemplate {
cachedTemplate := & CachedTemplate {
LoadPatterns: loadPatterns ,
Pre LoadTemplate Patterns: loadPatterns ,
cachedTmpl : nil ,
cachedTmpl : nil ,
}
}
template . Must ( cachedTemplate . Load ( template . New ( "" ) ) )
template . Must ( cachedTemplate . Load ( template . New ( "" ) ) )
return cachedTemplate
return cachedTemplate
}
}
// Load returns the cached template or loads it from disk using the list of preload (glob) patterns.
func ( ct * CachedTemplate ) Load ( t * template . Template ) ( * template . Template , error ) {
func ( ct * CachedTemplate ) Load ( t * template . Template ) ( * template . Template , error ) {
if ct . cachedTmpl != nil {
if ct . cachedTmpl != nil {
return ct . cachedTmpl , nil
return ct . cachedTmpl , nil
@ -31,7 +35,7 @@ func (ct *CachedTemplate) Load(t *template.Template) (*template.Template, error)
ct . cachedTmpl = t
ct . cachedTmpl = t
for _ , pattern := range ct . LoadPatterns {
for _ , pattern := range ct . Pre LoadTemplate Patterns {
var err error
var err error
ct . cachedTmpl , err = ct . cachedTmpl . ParseGlob ( pattern )
ct . cachedTmpl , err = ct . cachedTmpl . ParseGlob ( pattern )
if err != nil {
if err != nil {
@ -42,38 +46,43 @@ func (ct *CachedTemplate) Load(t *template.Template) (*template.Template, error)
return ct . cachedTmpl , nil
return ct . cachedTmpl , nil
}
}
// Reload the pattern from disk (used for developing)
func ( ct * CachedTemplate ) Reload ( ) {
func ( ct * CachedTemplate ) Reload ( ) {
ct . cachedTmpl = nil
ct . cachedTmpl = nil
template . Must ( ct . Load ( nil ) )
template . Must ( ct . Load ( nil ) )
}
}
// Template returns the cached template
func ( ct * CachedTemplate ) Template ( ) * template . Template {
func ( ct * CachedTemplate ) Template ( ) * template . Template {
log . Printf ( "preloadPatterns: %v" , ct . PreLoadTemplatePatterns )
return ct . cachedTmpl
return ct . cachedTmpl
}
}
// Renderer holds cached templates for rendering
// TODO: Add a render function to CachedTemplate instead of returning the template reference. In this way the Template Renderer would not have a "direct" dependency on "html/template"...
type Renderer struct {
rootPath string
// TemplateRenderer holds cached templates for rendering
loadPatterns [ ] string
type TemplateRenderer struct {
templateCache map [ string ] * CachedTemplate
viewsDir string
preloadTemplatePatterns [ ] string
templateCache map [ string ] * CachedTemplate
}
}
// NewRenderer constructs a template renderer with a base file
// NewRenderer constructs a template renderer with a base file
func NewRenderer ( rootPath string , loadPatterns ... string ) * Renderer {
func NewRenderer ( rootPath string , loadPatterns ... string ) * Template Renderer {
return & Renderer{
return & Template Renderer{
rootPath ,
rootPath ,
loadPatterns ,
loadPatterns ,
map [ string ] * CachedTemplate { } ,
map [ string ] * CachedTemplate { } ,
}
}
}
}
func ( r * Renderer) Load ( name string ) * CachedTemplate {
func ( r * Template Renderer) Load ( name string ) * CachedTemplate {
cachedTemplate , present := r . templateCache [ name ]
cachedTemplate , present := r . templateCache [ name ]
if ! present {
if ! present {
loaders := [ ] string { }
loaders := [ ] string { }
loaders = append ( loaders , r . loadPatterns... )
loaders = append ( loaders , r . pre loadTemplate Patterns... )
loaders = append ( loaders , path . Join ( r . rootPath , name ) )
loaders = append ( loaders , path . Join ( r . viewsDi r, name ) )
cachedTemplate = NewCacheTemplate ( loaders ... )
cachedTemplate = NewCacheTemplate ( loaders ... )
r . templateCache [ name ] = cachedTemplate
r . templateCache [ name ] = cachedTemplate
}
}
@ -82,7 +91,7 @@ func (r *Renderer) Load(name string) *CachedTemplate {
}
}
// Render the template, also injects "Page" and "Config" values in the template
// Render the template, also injects "Page" and "Config" values in the template
func ( r * Renderer) Render ( w io . Writer , name string , data util . H ) error {
func ( r * Template Renderer) Render ( w io . Writer , name string , data util . H ) error {
cachedTemplate := r . Load ( name )
cachedTemplate := r . Load ( name )
if config . Mode == "development" {
if config . Mode == "development" {