英文:
Go template function
问题
它注意到了使用Funcs
和FuncMap
时Go模板的一个奇怪的问题。以下代码按预期工作:
buffer := bytes.NewBufferString("")
funcMap := template.FuncMap{
"label": strings.Title,
}
t, _ := template.New("alex").Funcs(funcMap).Parse("{{label \"alex\"}}")
t.Execute(buffer, "")
return string(buffer.Bytes()) // => "Alex"
但是当我尝试将模板放在一个文件中时,它不起作用(Execute()
显示:“alex
是一个不完整或空的模板”):
t, _ := template.New("alex").Funcs(funcMap).ParseFiles("template.html")
使用template.html:
{{label "alex"}}
有什么想法为什么会这样?这是一个bug吗?有没有更简单的方法在模板中使用方法/函数?
英文:
It noticed a weird thing with Go templates when I try to use Funcs
and FuncMap
. The following code works as expected:
buffer := bytes.NewBufferString("")
funcMap := template.FuncMap{
"label": strings.Title,
}
t, _ := template.New("alex").Funcs(funcMap).Parse("{{label \"alex\"}}")
t.Execute(buffer, "")
return string(buffer.Bytes()) //=> "Alex"
But when I try to put the template in a file, it does not work (Execute()
says: "alex" is an incomplete or empty template
):
t, _ := template.New("alex").Funcs(funcMap).ParseFiles("template.html")
With template.html:
{{label \"alex\"}}
Any idea why ? Is this a bug ? Are there simpler ways to use methods/functions in templates ?
答案1
得分: 34
ParseFiles可能需要更好的文档。一个模板对象可以包含多个模板,每个模板都有一个名称。如果你查看ParseFiles的实现,你会发现它使用filename作为模板对象内部的模板名称。所以,将文件命名为与模板对象相同的名称(可能通常不实际),或者使用ExecuteTemplate而不仅仅是Execute。
英文:
ParseFiles could probably use better documentation. A template object can have multiple templates in it and each one has a name. If you look at the implementation of ParseFiles, you see that it uses the filename as the template name inside of the template object. So, name your file the same as the template object, (probably not generally practical) or else use ExecuteTemplate instead of just Execute.
答案2
得分: 15
Sonia的答案在技术上是正确的,但让我更加困惑。以下是我最终让它工作的方法:
t, err := template.New("_base.html").Funcs(funcs).ParseFiles("../view/_base.html", "../view/home.html")
if err != nil {
fmt.Fprint(w, "错误:", err)
fmt.Println("错误:", err)
return
}
err = t.Execute(w, data)
if err != nil {
fmt.Fprint(w, "错误:", err)
fmt.Println("错误:", err)
}
模板的名称是模板的纯文件名,而不是完整路径。如果默认模板的名称与之匹配,Execute
将执行默认模板,因此不需要使用ExecuteTemplate
。
在这种情况下,_base.html
文件是最外层的容器,例如:
<!DOCTYPE html>
<html><body>
<h1>{{ template "title" }}</h1>
{{ template "content" }}
</body></html>
而home.html
定义了具体的部分:
{{ define "title" }}Home{{ end }}
{{ define "content" }}
Stuff
{{ end }}
英文:
Sonia's answer is technically correct but left me even more confused. Here's how I eventually got it working:
t, err := template.New("_base.html").Funcs(funcs).ParseFiles("../view/_base.html", "../view/home.html")
if err != nil {
fmt.Fprint(w, "Error:", err)
fmt.Println("Error:", err)
return
}
err = t.Execute(w, data)
if err != nil {
fmt.Fprint(w, "Error:", err)
fmt.Println("Error:", err)
}
The name of the template is the bare filename of the template, not the complete path. Execute
will execute the default template provided it's named to match, so there's no need to use ExecuteTemplate
.
In this case, _base.html
file is the outermost container, eg:
<!DOCTYPE html>
<html><body>
<h1>{{ template "title" }}</h1>
{{ template "content" }}
</body></html>
while home.html
defines the specific parts:
{{ define "title" }}Home{{ end }}
{{ define "content" }}
Stuff
{{ end }}
答案3
得分: 0
你需要首先解析所有的文件并执行它们。你不能直接访问所有的文件。
英文:
you need to first parse all the files and execute them .you cannot direclty access all the files .
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论