Home > Blockchain >  Custom function is not working in template
Custom function is not working in template

Time:11-10

I've the below that is working fine playground

package main

import (
    "html/template"
    "os"
)

func main() {
    tmpl := `
{{ $slice := mkSlice "a" 5 "b" }}
{{ range $slice }}
     {{ . }}
{{ end }}
`
    funcMap := map[string]interface{}{"mkSlice": mkSlice}
    t := template.New("").Funcs(template.FuncMap(funcMap))
    template.Must(t.Parse(tmpl))
    t.Execute(os.Stdout, nil)
}

func mkSlice(args ...interface{}) []interface{} {
    return args
}

But once I tried to run in from template file, nothing had been displayed, and no error had been recieved!

func mkSlice(args ...interface{}) []interface{} { // to ceate the array in the template
    return args
}

funcMap := map[string]interface{}{"mkSlice": mkSlice}
tmpl := template.New("").Funcs(template.FuncMap(funcMap))
template.Must(tmpl.ParseFiles("index.html"))
tmpl.Execute(w, nil)

And index.html is:

{{ $slice := mkSlice "a" 5 "b" }}
{{ range $slice }}
    <span> {{ . }} </span>
{{ end }}

any thought?

CodePudding user response:

You don't see any errors because you don't check the error returned by tmpl.Execute(w, nil). When do check it:

if err := t.Execute(os.Stdout, nil); err != nil {
    panic(err)
}

You'll see an output like:

panic: template: "" is an incomplete or empty template

The difference is that in the first case you used Template.Parse() method which:

... parses text as a template body for t.

Note that the template text you parse will be used for t itself!

In the second case you used Template.ParseFiles() which:

... parses the named files and associates the resulting templates with t. If an error occurs, parsing stops and the returned template is nil; otherwise it is t. There must be at least one file. Since the templates created by ParseFiles are named by the base names of the argument files, t should usually have the name of one of the (base) names of the files.

So in your first example t contains a single template, and that single template will be executed by Template.Execute().

In your second example t contains multiple associated templates, t itself being an empty template, and another, associated template named index.html. You may execute that template using Template.ExecuteTemplate():

if err := t.ExecuteTemplate(os.Stdout, "index.html", nil); err != nil {
    panic(err)
}

For more information, see:

Go template name

The Go Template ParseFiles func parsing multiple files

  • Related