mirror of
https://github.com/kataras/iris.git
synced 2026-01-07 20:17:05 +00:00
accesslog: NEW log broker and many more features
some fixes about context clone, fix response recorder concurrent access, fix reload views with only ParseTemplate and more
This commit is contained in:
@@ -110,6 +110,11 @@ type noOpFS struct{}
|
||||
|
||||
func (fs noOpFS) Open(name string) (http.File, error) { return nil, nil }
|
||||
|
||||
func isNoOpFS(fs http.FileSystem) bool {
|
||||
_, ok := fs.(noOpFS)
|
||||
return ok
|
||||
}
|
||||
|
||||
// fixes: "invalid character in file path"
|
||||
// on amber engine (it uses the virtual fs directly
|
||||
// and it uses filepath instead of the path package...).
|
||||
|
||||
54
view/html.go
54
view/html.go
@@ -32,11 +32,18 @@ type HTMLEngine struct {
|
||||
funcs template.FuncMap
|
||||
|
||||
//
|
||||
middleware func(name string, contents []byte) (string, error)
|
||||
Templates *template.Template
|
||||
middleware func(name string, contents []byte) (string, error)
|
||||
Templates *template.Template
|
||||
customCache []customTmp // required to load them again if reload is true.
|
||||
//
|
||||
}
|
||||
|
||||
type customTmp struct {
|
||||
name string
|
||||
contents []byte
|
||||
funcs template.FuncMap
|
||||
}
|
||||
|
||||
var (
|
||||
_ Engine = (*HTMLEngine)(nil)
|
||||
_ EngineFuncer = (*HTMLEngine)(nil)
|
||||
@@ -215,6 +222,17 @@ func (s *HTMLEngine) Funcs(funcMap template.FuncMap) *HTMLEngine {
|
||||
//
|
||||
// Returns an error if something bad happens, caller is responsible to handle that.
|
||||
func (s *HTMLEngine) Load() error {
|
||||
s.rmu.Lock()
|
||||
defer s.rmu.Unlock()
|
||||
|
||||
return s.load()
|
||||
}
|
||||
|
||||
func (s *HTMLEngine) load() error {
|
||||
if err := s.reloadCustomTemplates(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return walk(s.fs, s.rootDir, func(path string, info os.FileInfo, err error) error {
|
||||
if info == nil || info.IsDir() {
|
||||
return nil
|
||||
@@ -231,15 +249,35 @@ func (s *HTMLEngine) Load() error {
|
||||
return fmt.Errorf("%s: %w", path, err)
|
||||
}
|
||||
|
||||
return s.ParseTemplate(path, buf, nil)
|
||||
return s.parseTemplate(path, buf, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *HTMLEngine) reloadCustomTemplates() error {
|
||||
for _, tmpl := range s.customCache {
|
||||
if err := s.parseTemplate(tmpl.name, tmpl.contents, tmpl.funcs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseTemplate adds a custom template to the root template.
|
||||
func (s *HTMLEngine) ParseTemplate(name string, contents []byte, funcs template.FuncMap) (err error) {
|
||||
s.rmu.Lock()
|
||||
defer s.rmu.Unlock()
|
||||
|
||||
s.customCache = append(s.customCache, customTmp{
|
||||
name: name,
|
||||
contents: contents,
|
||||
funcs: funcs,
|
||||
})
|
||||
|
||||
return s.parseTemplate(name, contents, funcs)
|
||||
}
|
||||
|
||||
func (s *HTMLEngine) parseTemplate(name string, contents []byte, funcs template.FuncMap) (err error) {
|
||||
s.initRootTmpl()
|
||||
|
||||
name = strings.TrimPrefix(name, "/")
|
||||
@@ -270,6 +308,7 @@ func (s *HTMLEngine) initRootTmpl() { // protected by the caller.
|
||||
// the root template should be the same,
|
||||
// no matter how many reloads as the
|
||||
// following unexported fields cannot be modified.
|
||||
// However, on reload they should be cleared otherwise we get an error.
|
||||
s.Templates = template.New(s.rootDir)
|
||||
s.Templates.Delims(s.left, s.right)
|
||||
}
|
||||
@@ -349,7 +388,14 @@ func (s *HTMLEngine) runtimeFuncsFor(t *template.Template, name string, binding
|
||||
func (s *HTMLEngine) ExecuteWriter(w io.Writer, name string, layout string, bindingData interface{}) error {
|
||||
// re-parse the templates if reload is enabled.
|
||||
if s.reload {
|
||||
if err := s.Load(); err != nil {
|
||||
s.rmu.Lock()
|
||||
defer s.rmu.Unlock()
|
||||
|
||||
s.Templates = nil
|
||||
// we lose the templates parsed manually, so store them when it's called
|
||||
// in order for load to take care of them too.
|
||||
|
||||
if err := s.load(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
11
view/jet.go
11
view/jet.go
@@ -178,9 +178,6 @@ func (s *JetEngine) AddVar(key string, value interface{}) {
|
||||
// not safe concurrent access across clients, use it only on development state.
|
||||
func (s *JetEngine) Reload(developmentMode bool) *JetEngine {
|
||||
s.developmentMode = developmentMode
|
||||
if s.Set != nil {
|
||||
s.Set.SetDevelopmentMode(developmentMode)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -215,7 +212,6 @@ func (l *jetLoader) Exists(name string) (string, bool) {
|
||||
// Load should load the templates from a physical system directory or by an embedded one (assets/go-bindata).
|
||||
func (s *JetEngine) Load() error {
|
||||
s.initSet()
|
||||
|
||||
// Note that, unlike the rest of template engines implementations,
|
||||
// we don't call the Set.GetTemplate to parse the templates,
|
||||
// we let it to the jet template parser itself which does that at serve-time and caches each template by itself.
|
||||
@@ -236,7 +232,12 @@ func (s *JetEngine) initSet() {
|
||||
s.mu.Lock()
|
||||
if s.Set == nil {
|
||||
s.Set = jet.NewHTMLSetLoader(s.loader)
|
||||
s.Set.SetDevelopmentMode(s.developmentMode)
|
||||
if s.developmentMode && !isNoOpFS(s.fs) {
|
||||
// this check is made to avoid jet's fs lookup on noOp fs (nil passed by the developer).
|
||||
// This can be produced when nil fs passed
|
||||
// and only `ParseTemplate` is used.
|
||||
s.Set.SetDevelopmentMode(true)
|
||||
}
|
||||
|
||||
if s.vars != nil {
|
||||
for key, value := range s.vars {
|
||||
|
||||
Reference in New Issue
Block a user