diff --git a/config/render.go b/config/render.go index 8037f3d3..2c2ca0bb 100644 --- a/config/render.go +++ b/config/render.go @@ -126,7 +126,7 @@ type ( Right string // Funcs like html/template Funcs map[string]interface{} - // Funcs like html/template + // LayoutFuncs like html/template // the difference from Funcs is that these funcs // can be used inside a layout and can override the predefined (yield,partial...) or add more custom funcs // these can override the Funcs inside no-layout templates also, use it when you know what you're doing @@ -146,9 +146,14 @@ type ( } // Jade the configs for JadeEngine - // Jade empty for now - // stay tuned Jade struct { + // Funcs like html/template + Funcs map[string]interface{} + // LayoutFuncs like html/template + // the difference from Funcs is that these funcs + // can be used inside a layout and can override the predefined (yield,partial...) or add more custom funcs + // these can override the Funcs inside no-layout templates also, use it when you know what you're doing + LayoutFuncs map[string]interface{} } // Amber the configs for AmberEngine @@ -211,7 +216,7 @@ func DefaultTemplate() Template { Pongo: Pongo{Filters: make(map[string]pongo2.FilterFunction, 0), Globals: make(map[string]interface{}, 0)}, Markdown: Markdown{Sanitize: false}, Amber: Amber{Funcs: template.FuncMap{}}, - Jade: Jade{}, + Jade: Jade{Funcs: template.FuncMap{}, LayoutFuncs: template.FuncMap{}}, } } diff --git a/iris.go b/iris.go index 76cab2c7..806f8390 100644 --- a/iris.go +++ b/iris.go @@ -122,6 +122,7 @@ func (s *Iris) initTemplates() { ///TODO gia AMber episis if templateConfig.Engine == config.HTMLEngine || templateConfig.Engine == config.AmberEngine { funcs := map[string]interface{}{ + "url": func(routeName string, args ...interface{}) (string, error) { r := s.RouteByName(routeName) // check if not found @@ -137,11 +138,11 @@ func (s *Iris) initTemplates() { // these should be already a non-nil map but if .New(cfg) it's not, is mergo's bug, temporary: if templateConfig.Engine == config.HTMLEngine { if templateConfig.HTMLTemplate.LayoutFuncs == nil { - templateConfig.HTMLTemplate.LayoutFuncs = make(map[string]interface{}, 1) + templateConfig.HTMLTemplate.LayoutFuncs = make(map[string]interface{}, len(funcs)) } if templateConfig.HTMLTemplate.Funcs == nil { - templateConfig.HTMLTemplate.Funcs = make(map[string]interface{}, 1) + templateConfig.HTMLTemplate.Funcs = make(map[string]interface{}, len(funcs)) } for k, v := range funcs { @@ -158,7 +159,7 @@ func (s *Iris) initTemplates() { } else if templateConfig.Engine == config.AmberEngine { if templateConfig.Amber.Funcs == nil { - templateConfig.Amber.Funcs = make(map[string]interface{}, 1) + templateConfig.Amber.Funcs = make(map[string]interface{}, len(funcs)) } for k, v := range funcs { @@ -171,8 +172,8 @@ func (s *Iris) initTemplates() { // } else if templateConfig.Engine == config.PongoEngine { - if templateConfig.Pongo.Filters == nil { - templateConfig.Pongo.Filters = make(map[string]pongo2.FilterFunction, 1) + if templateConfig.Pongo.Globals == nil { + templateConfig.Pongo.Globals = make(map[string]interface{}, 1) } urlFunc := func(routeName string, args ...interface{}) (out *pongo2.Value) { diff --git a/render/template/engine/html/html.go b/render/template/engine/html/html.go index f46786b7..404a0a1c 100644 --- a/render/template/engine/html/html.go +++ b/render/template/engine/html/html.go @@ -18,9 +18,6 @@ type ( Engine struct { Config *config.Template Templates *template.Template - // emptyFuncs returns empty functions, contains empty result for custom LayoutFuncs - - emptyFuncs template.FuncMap // Middleware // Note: // I see that many template engines returns html/template as result @@ -30,25 +27,23 @@ type ( } ) +var emptyFuncs = template.FuncMap{ + "yield": func() (string, error) { + return "", fmt.Errorf("yield was called, yet no layout defined") + }, + "partial": func() (string, error) { + return "", fmt.Errorf("block was called, yet no layout defined") + }, + "current": func() (string, error) { + return "", nil + }, "render": func(string) (string, error) { + return "", nil + }, +} + // New creates and returns the HTMLTemplate template engine func New(c config.Template) *Engine { s := &Engine{Config: &c} - funcs := template.FuncMap{ - "yield": func() (string, error) { - return "", fmt.Errorf("yield was called, yet no layout defined") - }, - "partial": func() (string, error) { - return "", fmt.Errorf("block was called, yet no layout defined") - }, - "current": func() (string, error) { - return "", nil - }, "render": func() (string, error) { - return "", nil - }, - } - - s.emptyFuncs = funcs - return s } @@ -122,11 +117,11 @@ func (s *Engine) buildFromDir() error { } // Add our funcmaps. - if s.Config.HTMLTemplate.Funcs != nil { - tmpl.Funcs(s.Config.HTMLTemplate.Funcs) - } + //if s.Config.HTMLTemplate.Funcs != nil { + // tmpl.Funcs(s.Config.HTMLTemplate.Funcs) + //} - tmpl.Funcs(s.emptyFuncs).Parse(contents) + tmpl.Funcs(s.Config.HTMLTemplate.Funcs).Parse(contents) break } } @@ -169,11 +164,11 @@ func (s *Engine) buildFromAsset() error { // Add our funcmaps. //for _, funcs := range s.Config.HTMLTemplate.Funcs { - if s.Config.HTMLTemplate.Funcs != nil { + /*if s.Config.HTMLTemplate.Funcs != nil { tmpl.Funcs(s.Config.HTMLTemplate.Funcs) - } + }*/ - tmpl.Funcs(s.emptyFuncs).Parse(string(buf)) + tmpl.Funcs(emptyFuncs).Funcs(s.Config.HTMLTemplate.Funcs).Parse(string(buf)) break } } @@ -183,10 +178,25 @@ func (s *Engine) buildFromAsset() error { func (s *Engine) executeTemplateBuf(name string, binding interface{}) (*bytes.Buffer, error) { buf := new(bytes.Buffer) + /* + var err error + if s.Middleware != nil { + contents, err := s.Middleware(name, buf.String()) + if err != nil { + return buf, err + } + buf.WriteString(contents) + } + */ err := s.Templates.ExecuteTemplate(buf, name, binding) + return buf, err } +func (s *Engine) ExecuteTemplateBuf(name string, binding interface{}) (*bytes.Buffer, error) { + return s.executeTemplateBuf(name, binding) +} + func (s *Engine) layoutFuncsFor(name string, binding interface{}) { funcs := template.FuncMap{ "yield": func() (template.HTML, error) { @@ -208,6 +218,7 @@ func (s *Engine) layoutFuncsFor(name string, binding interface{}) { }, "render": func(fullPartialName string) (template.HTML, error) { buf, err := s.executeTemplateBuf(fullPartialName, binding) + println("html.go:217-> " + buf.String()) // Return safe HTML here since we are rendering our own template. return template.HTML(buf.String()), err }, @@ -226,8 +237,9 @@ func (s *Engine) layoutFuncsFor(name string, binding interface{}) { // ExecuteWriter executes a templates and write its results to the out writer func (s *Engine) ExecuteWriter(out io.Writer, name string, binding interface{}, layout string) error { if layout != "" && layout != config.NoLayout { - s.layoutFuncsFor(name, binding) name = layout } + s.layoutFuncsFor(name, binding) + return s.Templates.ExecuteTemplate(out, name, binding) } diff --git a/render/template/engine/jade/jade.go b/render/template/engine/jade/jade.go index bbf2c457..92ce8119 100644 --- a/render/template/engine/jade/jade.go +++ b/render/template/engine/jade/jade.go @@ -13,10 +13,12 @@ type Engine struct { // New creates and returns a new JadeEngine with its configs func New(cfg config.Template) *Engine { - + cfg.HTMLTemplate.Funcs = cfg.Jade.Funcs //copy the jade's funcs to the underline HTMLEngine + cfg.HTMLTemplate.LayoutFuncs = cfg.Jade.LayoutFuncs underline := &Engine{Engine: html.New(cfg)} underline.Middleware = func(relativeName string, fileContents string) (string, error) { return jade.Parse(relativeName, fileContents) } + return underline }