自定义函数在模板中不起作用

Custom function is not working in template

我有下面的工作正常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
}

但是当我尝试从模板文件中 运行 时,没有显示任何内容,也没有收到任何错误!

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)

index.html是:

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

有什么想法吗?

您没有看到任何错误,因为您没有检查 tmpl.Execute(w, nil) 返回的错误。什么时候检查:

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

您会看到如下输出:

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

不同之处在于,在第一种情况下,您使用了 Template.Parse() 方法,其中:

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

请注意,您解析的模板文本将用于 t 本身!

在第二种情况下,您使用了 Template.ParseFiles(),其中:

... 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.

因此在您的第一个示例中 t 包含一个模板,并且该模板将由 Template.Execute() 执行。

在您的第二个示例中,t 包含多个关联模板,t 本身是一个空模板,另一个关联模板名为 index.html。您可以使用 Template.ExecuteTemplate():

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

有关详细信息,请参阅: