mirror of
https://github.com/kataras/iris.git
synced 2025-03-15 03:56:27 +01:00
Extend the Handlebars support as requested here https://github.com/kataras/iris/issues/239#issuecomment-229020737
History, Books & examples are updated.
This commit is contained in:
parent
aa319fd8e4
commit
7e9dc068fb
18
HISTORY.md
18
HISTORY.md
|
@ -1,9 +1,23 @@
|
||||||
# History
|
# History
|
||||||
|
|
||||||
## 3.0.0-rc.2 -> 3.0.0-rc.3
|
|
||||||
|
|
||||||
**How to upgrade**: remove your $GOPATH/src/github.com/kataras folder, open your command-line and run `go get -u github.com/kataras/iris/iris`.
|
**How to upgrade**: remove your $GOPATH/src/github.com/kataras folder, open your command-line and run `go get -u github.com/kataras/iris/iris`.
|
||||||
|
|
||||||
|
## 3.0.0-rc.3 -> 3.0.0-rc.4
|
||||||
|
|
||||||
|
**NEW**: **Handlebars** template engine support with all Iris' view engine's functions/helpers support:
|
||||||
|
- `iris.Config.Render.Template.Layout = "layouts/layout.html"`
|
||||||
|
- `config.NoLayout`
|
||||||
|
- **dynamic** optional layout on `context.Render`
|
||||||
|
- **Party specific** layout
|
||||||
|
- `iris.Config.Render.Template.Handlebars.Helpers["myhelper"] = func()...`
|
||||||
|
- `{{ yield }} `
|
||||||
|
- `{{ render }}`
|
||||||
|
- `{{ url "myroute" myparams}}`
|
||||||
|
- `{{ urlpath "myroute" myparams}}`
|
||||||
|
|
||||||
|
For a complete example please navigate [here](https://github.com/iris-contrib/examples/tree/master/templates_handlebars/templates).
|
||||||
|
|
||||||
|
## 3.0.0-rc.2 -> 3.0.0-rc.3
|
||||||
|
|
||||||
**Breaking changes**
|
**Breaking changes**
|
||||||
- Move middleware & their configs to the [iris-contrib/middleware](https://github.com/iris-contrib/middleware) repository
|
- Move middleware & their configs to the [iris-contrib/middleware](https://github.com/iris-contrib/middleware) repository
|
||||||
|
|
|
@ -476,7 +476,7 @@ func (ctx *Context) Render(name string, binding interface{}, layout ...string) e
|
||||||
func (ctx *Context) MustRender(name string, binding interface{}, layout ...string) {
|
func (ctx *Context) MustRender(name string, binding interface{}, layout ...string) {
|
||||||
if err := ctx.Render(name, binding, layout...); err != nil {
|
if err := ctx.Render(name, binding, layout...); err != nil {
|
||||||
ctx.Panic()
|
ctx.Panic()
|
||||||
ctx.framework.Logger.Dangerf("MustRender panics for client with IP: %s On template: %s", ctx.RemoteAddr(), name)
|
ctx.framework.Logger.Dangerf("MustRender panics for client with IP: %s On template: %s.Trace: %s\n", ctx.RemoteAddr(), name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ func init() {
|
||||||
|
|
||||||
const (
|
const (
|
||||||
/* conversional */
|
/* conversional */
|
||||||
|
|
||||||
// HTMLEngine conversion for config.HTMLEngine
|
// HTMLEngine conversion for config.HTMLEngine
|
||||||
HTMLEngine = config.HTMLEngine
|
HTMLEngine = config.HTMLEngine
|
||||||
// PongoEngine conversion for config.PongoEngine
|
// PongoEngine conversion for config.PongoEngine
|
||||||
|
|
|
@ -39,6 +39,17 @@ func (e *Engine) BuildTemplates() error {
|
||||||
if e.Config.Handlebars.Helpers != nil {
|
if e.Config.Handlebars.Helpers != nil {
|
||||||
raymond.RegisterHelpers(e.Config.Handlebars.Helpers)
|
raymond.RegisterHelpers(e.Config.Handlebars.Helpers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
raymond.RegisterHelper("render", func(partial string, binding interface{}) raymond.SafeString {
|
||||||
|
contents, err := e.executeTemplateBuf(partial, binding)
|
||||||
|
if err != nil {
|
||||||
|
return raymond.SafeString("Template with name: " + partial + " couldn't not be found.")
|
||||||
|
}
|
||||||
|
return raymond.SafeString(contents)
|
||||||
|
})
|
||||||
|
|
||||||
var templateErr error
|
var templateErr error
|
||||||
|
|
||||||
dir := e.Config.Directory
|
dir := e.Config.Directory
|
||||||
|
@ -84,6 +95,7 @@ func (e *Engine) BuildTemplates() error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return templateErr
|
return templateErr
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -98,13 +110,53 @@ func (e *Engine) fromCache(relativeName string) *raymond.Template {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Engine) executeTemplateBuf(name string, binding interface{}) (string, error) {
|
||||||
|
if tmpl := e.fromCache(name); tmpl != nil {
|
||||||
|
return tmpl.Exec(binding)
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
// ExecuteWriter executes a templates and write its results to the out writer
|
// ExecuteWriter executes a templates and write its results to the out writer
|
||||||
func (e *Engine) ExecuteWriter(out io.Writer, name string, binding interface{}, layout string) error {
|
func (e *Engine) ExecuteWriter(out io.Writer, name string, binding interface{}, layout string) error {
|
||||||
if tmpl := e.fromCache(name); tmpl != nil {
|
|
||||||
|
isLayout := false
|
||||||
|
|
||||||
|
renderFilename := name
|
||||||
|
if layout != "" && layout != config.NoLayout {
|
||||||
|
isLayout = true
|
||||||
|
renderFilename = layout // the render becomes the layout, and the name is the partial.
|
||||||
|
}
|
||||||
|
|
||||||
|
if tmpl := e.fromCache(renderFilename); tmpl != nil {
|
||||||
|
if isLayout {
|
||||||
|
var context map[string]interface{}
|
||||||
|
if m, is := binding.(map[string]interface{}); is { //handlebars accepts maps,
|
||||||
|
context = m
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Please provide a map[string]interface{} type as the binding instead of the %#v", binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
contents, err := e.executeTemplateBuf(name, binding)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if context == nil {
|
||||||
|
context = make(map[string]interface{}, 1)
|
||||||
|
}
|
||||||
|
// I'm implemented the {{ yield }} as with the rest of template engines, so this is not inneed for iris, but the user can do that manually if want
|
||||||
|
// there is no performanrce different: raymond.RegisterPartialTemplate(name, tmpl)
|
||||||
|
context["yield"] = raymond.SafeString(contents)
|
||||||
|
}
|
||||||
|
|
||||||
res, err := tmpl.Exec(binding)
|
res, err := tmpl.Exec(binding)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
_, err = fmt.Fprint(out, res)
|
_, err = fmt.Fprint(out, res)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("[IRIS TEMPLATES] Template with name %s doesn't exists in the dir %s", name, e.Config.Directory)
|
return fmt.Errorf("[IRIS TEMPLATES] Template with name %s[original name = %s] doesn't exists in the dir %s", renderFilename, name, e.Config.Directory)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user