1
0
mirror of https://github.com/kataras/iris.git synced 2025-12-23 12:57:05 +00:00
Former-commit-id: 292d155c877ba3f9d1210db54c3df3fedd1d0c1c
This commit is contained in:
Gerasimos (Makis) Maropoulos
2018-01-15 00:54:01 +02:00
parent ad9c76adb3
commit a19e570c8a
19 changed files with 154 additions and 47 deletions

View File

@@ -10,6 +10,7 @@ import (
"path/filepath"
"strings"
"sync"
"time"
)
type (
@@ -20,7 +21,7 @@ type (
extension string
assetFn func(name string) ([]byte, error) // for embedded, in combination with directory & extension
namesFn func() []string // for embedded, in combination with directory & extension
reload bool // if true, each time the ExecuteWriter is called the templates will be reloaded.
reload bool // if true, each time the ExecuteWriter is called the templates will be reloaded, each ExecuteWriter waits to be finished before writing to a new one.
// parser configuration
options []string // text options
left string
@@ -32,7 +33,6 @@ type (
//
middleware func(name string, contents string) (string, error)
mu sync.Mutex // locks for template files loader
Templates *template.Template
//
}
@@ -94,6 +94,10 @@ func (s *HTMLEngine) Binary(assetFn func(name string) ([]byte, error), namesFn f
// Reload if setted to true the templates are reloading on each render,
// use it when you're in development and you're boring of restarting
// the whole app when you edit a template file.
//
// Note that if `true` is passed then only one `View -> ExecuteWriter` will be render each time,
// no concurrent access across clients, use it only on development status.
// It's good to be used side by side with the https://github.com/kataras/rizla reloader for go source files.
func (s *HTMLEngine) Reload(developmentMode bool) *HTMLEngine {
s.reload = developmentMode
return s
@@ -118,9 +122,9 @@ func (s *HTMLEngine) Reload(developmentMode bool) *HTMLEngine {
// Execution stops immediately with an error.
//
func (s *HTMLEngine) Option(opt ...string) *HTMLEngine {
s.mu.Lock()
s.rmu.Lock()
s.options = append(s.options, opt...)
s.mu.Unlock()
s.rmu.Unlock()
return s
}
@@ -180,6 +184,15 @@ func (s *HTMLEngine) AddFunc(funcName string, funcBody interface{}) {
//
// Returns an error if something bad happens, user is responsible to catch it.
func (s *HTMLEngine) Load() error {
// No need to make this with a complicated and "pro" way, just add lockers to the `ExecuteWriter`.
// if `Reload(true)` and add a note for non conc access on dev mode.
// atomic.StoreUint32(&s.isLoading, 1)
// s.rmu.Lock()
// defer func() {
// s.rmu.Unlock()
// atomic.StoreUint32(&s.isLoading, 0)
// }()
if s.assetFn != nil && s.namesFn != nil {
// NOT NECESSARY "fix" of https://github.com/kataras/iris/issues/784,
// IT'S BAD CODE WRITTEN WE KEEP HERE ONLY FOR A REMINDER
@@ -256,10 +269,10 @@ func (s *HTMLEngine) loadDirectory() error {
templateErr = err
return err
}
s.mu.Lock()
//s.mu.Lock()
// Add our funcmaps.
_, err = tmpl.Funcs(emptyFuncs).Funcs(s.funcs).Parse(contents)
s.mu.Unlock()
//s.mu.Unlock()
if err != nil {
templateErr = err
return err
@@ -406,11 +419,10 @@ func (s *HTMLEngine) layoutFuncsFor(name string, binding interface{}) {
return template.HTML(buf.String()), err
},
}
s.rmu.RLock()
for k, v := range s.layoutFuncs {
funcs[k] = v
}
s.rmu.RUnlock()
if tpl := s.Templates.Lookup(name); tpl != nil {
tpl.Funcs(funcs)
}
@@ -429,10 +441,16 @@ func (s *HTMLEngine) runtimeFuncsFor(name string, binding interface{}) {
}
}
var zero = time.Time{}
// ExecuteWriter executes a template and writes its result to the w writer.
func (s *HTMLEngine) ExecuteWriter(w io.Writer, name string, layout string, bindingData interface{}) error {
// reload the templates if reload configuration field is true
// re-parse the templates if reload is enabled.
if s.reload {
// locks to fix #872, it's the simplest solution and the most correct,
// to execute writers with "wait list", one at a time.
s.rmu.Lock()
defer s.rmu.Unlock()
if err := s.Load(); err != nil {
return err
}