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

huangapple go评论167阅读模式
英文:

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

有什么想法吗?

英文:

I've the below that is working fine playground

package main

import (
	&quot;html/template&quot;
	&quot;os&quot;
)

func main() {
	tmpl := `
{{ $slice := mkSlice &quot;a&quot; 5 &quot;b&quot; }}
{{ range $slice }}
     {{ . }}
{{ end }}
`
	funcMap := map[string]interface{}{&quot;mkSlice&quot;: mkSlice}
	t := template.New(&quot;&quot;).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{}{&quot;mkSlice&quot;: mkSlice}
tmpl := template.New(&quot;&quot;).Funcs(template.FuncMap(funcMap))
template.Must(tmpl.ParseFiles(&quot;index.html&quot;))
tmpl.Execute(w, nil)

And index.html is:

{{ $slice := mkSlice &quot;a&quot; 5 &quot;b&quot; }}
{{ range $slice }}
    &lt;span&gt; {{ . }} &lt;/span&gt;
{{ end }}

any thought?

答案1

得分: 2

你没有看到任何错误,因为你没有检查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()方法,它会:

> ...将文本解析为模板主体。

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

而在第二种情况下,你使用了Template.ParseFiles(),它会:

> ...解析指定的文件,并将生成的模板与t关联。如果发生错误,解析将停止,并且返回的模板为nil;否则为t。至少要有一个文件。由于ParseFiles创建的模板是根据参数文件的基本名称命名的,所以t通常应该具有文件名(基本名称)之一。

因此,在你的第一个示例中,t包含一个单独的模板,而这个单独的模板将由Template.Execute()执行。

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

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

更多信息,请参考:

https://stackoverflow.com/questions/41176355/go-template-name/41187671#41187671

https://stackoverflow.com/questions/44979276/the-go-template-parsefiles-func-parsing-multiple-files/44979550#44979550

英文:

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: &quot;&quot; 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, &quot;index.html&quot;, nil); err != nil {
	panic(err)
}

For more information, see:

https://stackoverflow.com/questions/41176355/go-template-name/41187671#41187671

https://stackoverflow.com/questions/44979276/the-go-template-parsefiles-func-parsing-multiple-files/44979550#44979550

huangapple
  • 本文由 发表于 2021年11月10日 01:30:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/69902571.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定