Skip to content

Commit

Permalink
Add template functions as html render option (#81)
Browse files Browse the repository at this point in the history
* Add template functions as html render option

* Fix breaking change
  • Loading branch information
brutella authored Apr 21, 2020
1 parent c524c18 commit b7b4713
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 13 deletions.
45 changes: 33 additions & 12 deletions render.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ type Options struct {
Layout string
// Extensions to parse template files from. Defaults to [".tmpl"].
Extensions []string
// Funcs is a slice of FuncMaps to apply to the template upon compilation. This is useful for helper functions. Defaults to [].
// Funcs is a slice of FuncMaps to apply to the template upon compilation. This is useful for helper functions. Defaults to empty map.
Funcs []template.FuncMap
// Delims sets the action delimiters to the specified strings in the Delims struct.
Delims Delims
Expand Down Expand Up @@ -109,6 +109,8 @@ type Options struct {
type HTMLOptions struct {
// Layout template name. Overrides Options.Layout.
Layout string
// Funcs added to Options.Funcs.
Funcs template.FuncMap
}

// Render is a service that provides functions for easily writing JSON, XML,
Expand Down Expand Up @@ -289,8 +291,8 @@ func (r *Render) execute(name string, binding interface{}) (*bytes.Buffer, error
return buf, r.templates.ExecuteTemplate(buf, name, binding)
}

func (r *Render) addLayoutFuncs(name string, binding interface{}) {
funcs := template.FuncMap{
func (r *Render) layoutFuncs(name string, binding interface{}) template.FuncMap {
return template.FuncMap{
"yield": func() (template.HTML, error) {
buf, err := r.execute(name, binding)
// Return safe HTML here since we are rendering our own template.
Expand Down Expand Up @@ -325,18 +327,32 @@ func (r *Render) addLayoutFuncs(name string, binding interface{}) {
return "", nil
},
}
if tpl := r.templates.Lookup(name); tpl != nil {
tpl.Funcs(funcs)
}
}

func (r *Render) prepareHTMLOptions(htmlOpt []HTMLOptions) HTMLOptions {
layout := r.opt.Layout
funcs := template.FuncMap{}

for _, tmp := range r.opt.Funcs {
for k, v := range tmp {
funcs[k] = v
}
}

if len(htmlOpt) > 0 {
return htmlOpt[0]
opt := htmlOpt[0]
if len(opt.Layout) > 0 {
layout = opt.Layout
}

for k, v := range opt.Funcs {
funcs[k] = v
}
}

return HTMLOptions{
Layout: r.opt.Layout,
Layout: layout,
Funcs: funcs,
}
}

Expand Down Expand Up @@ -374,10 +390,15 @@ func (r *Render) HTML(w io.Writer, status int, name string, binding interface{},
}

opt := r.prepareHTMLOptions(htmlOpt)
// Assign a layout if there is one.
if len(opt.Layout) > 0 {
r.addLayoutFuncs(name, binding)
name = opt.Layout
if tpl := r.templates.Lookup(name); tpl != nil {
if len(opt.Layout) > 0 {
tpl.Funcs(r.layoutFuncs(name, binding))
name = opt.Layout
}

if len(opt.Funcs) > 0 {
tpl.Funcs(opt.Funcs)
}
}

head := Head{
Expand Down
2 changes: 1 addition & 1 deletion render_html_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func TestHTMLFuncs(t *testing.T) {
render := New(Options{
Directory: "fixtures/custom_funcs",
Funcs: []template.FuncMap{
{
template.FuncMap{
"myCustomFunc": func() string {
return "My custom function"
},
Expand Down

0 comments on commit b7b4713

Please sign in to comment.