I am trying to achieve a function to add to FuncMaps in a base template, and this function should be used to render re-useable view components
For instance:
func (v *Item) RenderComponent(componentPath string, vars ...interface{}) template.HTML {
p := path.Join(v.folder, "components", componentPath)
// Get the pieces of the component path.
componentPathPieces := strings.Split(p, "/")
// Get the last item in the pieces (this should be the file name).
componentFileName := componentPathPieces[len(componentPathPieces)-1]
// Make the new template using component file name and add FuncMap functions.
t := template.New(componentFileName).Funcs(v.funcMap)
// Determine if there is an error in the template syntax.
t, err := template.ParseFiles(p + "." + v.extension)
if err != nil {
panic(err)
}
// Add variables to the component and write to a buffer.
b := new(bytes.Buffer)
if err = t.Execute(b, vars); err != nil {
panic(err)
}
// Return the contents of the template buffer as a string of HTML.
return template.HTML(b.String())
}
This code works just fine for a component that doesn't render another component. For example, I can write {{component "buttons/default-button" "some url goes here"}}
and it will render the component at components/button/default-button.tmpl
just fine.
However, if I include another component within that default-button component, such as {{component "icons/check-icon"}}
, I will get a large error (too big to paste here). But here is one of the error messages:
template: default-button.tmpl:4: function "component" not defined
As you can see, the error is thrown from the component file that is trying to call another component. I believe that happens because the viewFunc is either not being properly added, or is being recursively called in some way.