英文:
Why when I ignore the template.New() the program can run successfully?
问题
我正在尝试使用html/template
来解析一个结构化格式的JSON。
func handler(w http.ResponseWriter, r *http.Request) {
var issueList = template.Must(template.New("template01").ParseFiles("template01.tmpl"))
result, err := SearchIssues(os.Args[1:])
if err != nil {
log.Fatal(err)
}
if err := issueList.Execute(w, result); err != nil {
log.Fatal(err)
}
}
函数SearchIssues
用于将流转换为JSON格式,它工作正常。
然后我尝试使用html/template
来解析JSON:
var issueList = template.Must(template.New("template01").ParseFiles("template01.tmpl"))
当我访问本地服务时,出现错误:XXX是一个不完整或空的模板
。
但是当我删除New("template01").
后,程序可以正常运行。
像这样:
func handler(w http.ResponseWriter, r *http.Request) {
var issueList = template.Must(template.ParseFiles("template01.tmpl"))
result, err := SearchIssues(os.Args[1:])
if err != nil {
log.Fatal(err)
}
if err := issueList.Execute(w, result); err != nil {
log.Fatal(err)
}
}
我不是母语为英语的人,英语不是很好,抱歉。
英文:
I am trying to use html/template
to parse a JSON in struct format.
func handler(w http.ResponseWriter, r *http.Request) {
var issueList = template.Must(template.New("template01").ParseFiles("template01.tmpl"))
result, err := SearchIssues(os.Args[1:])
if err != nil {
log.Fatal(err)
}
if err := issueList.Execute(w, result); err != nil {
log.Fatal(err)
}
}
The function SearchIssues
is used to convert the stream into JSON format, it works well.
Then I try to parse the JSON by html/template
using
var issueList = template.Must(template.New("template01").ParseFiles("template01.tmpl"))
When I access local services, there is an error : XXX is an incomplete or empty template
.
But when I delete New("template01").
the program runs well.
Like this:
func handler(w http.ResponseWriter, r *http.Request) {
var issueList = template.Must(template.ParseFiles("template01.tmpl"))
result, err := SearchIssues(os.Args[1:])
if err != nil {
log.Fatal(err)
}
if err := issueList.Execute(w, result); err != nil {
log.Fatal(err)
}
}
I am not native speaker, English is not very well, sorry.
答案1
得分: 2
你的第一个代码的问题在于当你执行以下代码时:
var issueList = template.Must(template.New("template01").
ParseFiles("template01.tmpl"))
template.New()
会创建一个名为 "template01"
的新模板。变量 issueList
将引用这个空模板。你调用它的 Template.ParseFiles()
方法,它会解析 "template01.tmpl"
文件并创建一个关联的模板,命名为 "template01.tmpl"
。变量 issueList
仍然引用 template01
模板,而不是从文件解析出来的模板。当你调用 Template.Execute()
时,它执行 issueList
指定的(默认)模板,也就是空的 template01
。这就是为什么会出现 incomplete or empty template
错误的原因。
在你的第二个版本中:
var issueList = template.Must(template.ParseFiles("template01.tmpl"))
你调用了 template.ParseFiles()
函数,它解析了 "template01.tmpl"
文件,并返回它的模板。所以 issueList
将引用从文件解析出来的模板,而不是空模板。因此,Template.Execute()
将执行这个模板。
注意:如果在第一种情况下你使用 Template.ExecuteTemplate()
,你可以指定要执行的模板的名称:
if err := issueList.Execute(w, "template01.tmpl", result); err != nil {
log.Fatal(err)
}
这将成功,因为你明确告诉它执行从文件解析出来的 "template01.tmpl"
,而不是默认的空模板。
还要注意的是,你不应该在处理程序中解析模板,这样会很慢。在处理程序之前解析一次,将结果存储在包级别的变量中,然后在处理程序中只执行它即可。详细信息请参见 https://stackoverflow.com/questions/28451675/it-takes-too-much-time-when-using-template-package-to-generate-a-dynamic-web-p/28453523#28453523
关于关联模板的详细信息,请参见 https://stackoverflow.com/questions/41176355/go-template-name/41187671#41187671。
另外,请使用 encoding/json
生成 JSON 输出,而不是 text/template
或 html/template
。模板引擎对 JSON 格式和编码一无所知,很容易生成无效的 JSON。
英文:
The problem with your first code is that when you do:
var issueList = template.Must(template.New("template01").
ParseFiles("template01.tmpl"))
template.New()
will create a new template having the name "template01"
. The variable issueList
will refer to this empty template. You call its Template.ParseFiles()
method, which will parse the "template01.tmpl"
file and create an associated template named "template01.tmpl"
. The variable issueList
will still refer to the template01
template, not the one parsed from the file. When you call Template.Excute()
, it executes the (default) template issueList
designates, which is the empty template01
. That's why you get the error incomplete or empty template
.
In your second version:
var issueList = template.Must(template.ParseFiles("template01.tmpl"))
You call the template.ParseFiles()
function, which parses the "template01.tmpl"
file, and returns its template. So issueList
will refer to the parsed template from the file, and not an empty template. So Template.Execute()
will execute this template.
Note: if in the first case you'd use Template.ExecuteTemplate()
, you can name the template you want to execute:
if err := issueList.Execute(w, "template01.tmpl", result); err != nil {
log.Fatal(err)
}
This will succeed because you tell explicitly to execute the "template01.tmpl"
parsed from the file, and not the default, empty template.
Also note that you should not parse the templates in your handler, it's slow. Parse it before that once, store the result in package level variables and just execute it in the handler. For dteails, see https://stackoverflow.com/questions/28451675/it-takes-too-much-time-when-using-template-package-to-generate-a-dynamic-web-p/28453523#28453523
For details about associated templates, see https://stackoverflow.com/questions/41176355/go-template-name/41187671#41187671.
Also please use encoding/json
to generate JSON output and not text/template
or html/template
. The template engine knows nothing about JSON format and encoding, and may easily generate invalid JSON.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论