mirror of
https://github.com/kataras/iris.git
synced 2025-12-18 02:17:05 +00:00
Update to version 10.0.1 - read more at: https://github.com/kataras/iris/blob/master/HISTORY.md#mo-15-jenuary-2018--v1001
Former-commit-id: 292d155c877ba3f9d1210db54c3df3fedd1d0c1c
This commit is contained in:
@@ -20,9 +20,8 @@ type AmberEngine struct {
|
||||
namesFn func() []string // for embedded, in combination with directory & extension
|
||||
reload bool
|
||||
//
|
||||
rmu sync.RWMutex // locks for funcs
|
||||
rmu sync.RWMutex // locks for `ExecuteWiter` when `reload` is true.
|
||||
funcs map[string]interface{}
|
||||
mu sync.Mutex // locks for template files load
|
||||
templateCache map[string]*template.Template
|
||||
}
|
||||
|
||||
@@ -57,6 +56,10 @@ func (s *AmberEngine) Binary(assetFn func(name string) ([]byte, error), namesFn
|
||||
// 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 *AmberEngine) Reload(developmentMode bool) *AmberEngine {
|
||||
s.reload = developmentMode
|
||||
return s
|
||||
@@ -116,8 +119,6 @@ func (s *AmberEngine) loadDirectory() error {
|
||||
|
||||
templates, err := amber.CompileDir(dir, opt, amber.DefaultOptions) // this returns the map with stripped extension, we want extension so we copy the map
|
||||
if err == nil {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.templateCache = make(map[string]*template.Template)
|
||||
for k, v := range templates {
|
||||
name := filepath.ToSlash(k + opt.Ext)
|
||||
@@ -155,9 +156,6 @@ func (s *AmberEngine) loadAssets() error {
|
||||
}
|
||||
amber.FuncMap = funcs //set the funcs
|
||||
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
names := namesFn()
|
||||
|
||||
for _, path := range names {
|
||||
@@ -192,21 +190,22 @@ func (s *AmberEngine) loadAssets() error {
|
||||
}
|
||||
|
||||
func (s *AmberEngine) fromCache(relativeName string) *template.Template {
|
||||
s.mu.Lock()
|
||||
tmpl, ok := s.templateCache[relativeName]
|
||||
if ok {
|
||||
s.mu.Unlock()
|
||||
return tmpl
|
||||
}
|
||||
s.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExecuteWriter executes a template and writes its result to the w writer.
|
||||
// layout here is useless.
|
||||
func (s *AmberEngine) ExecuteWriter(w io.Writer, filename 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
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ type DjangoEngine struct {
|
||||
namesFn func() []string // for embedded, in combination with directory & extension
|
||||
reload bool
|
||||
//
|
||||
rmu sync.RWMutex // locks for filters and globals
|
||||
rmu sync.RWMutex // locks for filters, globals and `ExecuteWiter` when `reload` is true.
|
||||
// filters for pongo2, map[name of the filter] the filter function . The filters are auto register
|
||||
filters map[string]FilterFunction
|
||||
// globals share context fields between templates. https://github.com/flosch/pongo2/issues/35
|
||||
@@ -147,6 +147,10 @@ func (s *DjangoEngine) Binary(assetFn func(name string) ([]byte, error), namesFn
|
||||
// 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 *DjangoEngine) Reload(developmentMode bool) *DjangoEngine {
|
||||
s.reload = developmentMode
|
||||
return s
|
||||
@@ -373,8 +377,12 @@ func (s *DjangoEngine) fromCache(relativeName string) *pongo2.Template {
|
||||
// ExecuteWriter executes a templates and write its results to the w writer
|
||||
// layout here is useless.
|
||||
func (s *DjangoEngine) ExecuteWriter(w io.Writer, filename 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
|
||||
}
|
||||
|
||||
@@ -22,9 +22,8 @@ type HandlebarsEngine struct {
|
||||
reload bool // if true, each time the ExecuteWriter is called the templates will be reloaded.
|
||||
// parser configuration
|
||||
layout string
|
||||
rmu sync.RWMutex // locks for helpers
|
||||
rmu sync.RWMutex // locks for helpers and `ExecuteWiter` when `reload` is true.
|
||||
helpers map[string]interface{}
|
||||
mu sync.Mutex // locks for template files load
|
||||
templateCache map[string]*raymond.Template
|
||||
}
|
||||
|
||||
@@ -66,6 +65,10 @@ func (s *HandlebarsEngine) Binary(assetFn func(name string) ([]byte, error), nam
|
||||
// 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 *HandlebarsEngine) Reload(developmentMode bool) *HandlebarsEngine {
|
||||
s.reload = developmentMode
|
||||
return s
|
||||
@@ -123,8 +126,7 @@ func (s *HandlebarsEngine) loadDirectory() error {
|
||||
|
||||
// the render works like {{ render "myfile.html" theContext.PartialContext}}
|
||||
// instead of the html/template engine which works like {{ render "myfile.html"}} and accepts the parent binding, with handlebars we can't do that because of lack of runtime helpers (dublicate error)
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
var templateErr error
|
||||
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||
if info == nil || info.IsDir() {
|
||||
@@ -181,9 +183,6 @@ func (s *HandlebarsEngine) loadAssets() error {
|
||||
}
|
||||
var templateErr error
|
||||
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
names := namesFn()
|
||||
for _, path := range names {
|
||||
if !strings.HasPrefix(path, virtualDirectory) {
|
||||
@@ -219,14 +218,11 @@ func (s *HandlebarsEngine) loadAssets() error {
|
||||
}
|
||||
|
||||
func (s *HandlebarsEngine) fromCache(relativeName string) *raymond.Template {
|
||||
s.mu.Lock()
|
||||
tmpl, ok := s.templateCache[relativeName]
|
||||
if ok {
|
||||
s.mu.Unlock()
|
||||
return tmpl
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
s.mu.Unlock()
|
||||
return nil
|
||||
return tmpl
|
||||
}
|
||||
|
||||
func (s *HandlebarsEngine) executeTemplateBuf(name string, binding interface{}) (string, error) {
|
||||
@@ -238,8 +234,12 @@ func (s *HandlebarsEngine) executeTemplateBuf(name string, binding interface{})
|
||||
|
||||
// ExecuteWriter executes a template and writes its result to the w writer.
|
||||
func (s *HandlebarsEngine) ExecuteWriter(w io.Writer, filename 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
|
||||
}
|
||||
|
||||
36
view/html.go
36
view/html.go
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user