为什么template.ParseFiles()没有检测到这个错误?

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

Why doesn't template.ParseFiles() detect this error?

问题

如果我在模板文件中指定一个不存在的模板,ParseFiles()函数不会检测到错误,而是由ExecuteTemplate()函数检测到。人们会期望解析过程能够检测到任何缺失的模板。在解析过程中检测到这些错误也可以提高性能。

{{define "test"}}
<html>
    <head>
        <title> test </title>
    </head>
    <body>
        <h1> Hello, world!</h1>
        {{template "doesnotexist"}}
    </body>
</html>
{{end}}

main.go

package main

import (
    "html/template"
    "os"
    "fmt"
)

func main() {
    t, err := template.ParseFiles("test.html")
    if err != nil {
        fmt.Printf("ParseFiles: %s\n", err)
        return
    }

    err = t.ExecuteTemplate(os.Stdout, "test", nil)
    if err != nil {
        fmt.Printf("ExecuteTemplate: %s\n", err)
    }
}

输出结果:

ExecuteTemplate: html/template:test.html:8:19: no such template "doesnotexist"
英文:

If I specify a non-existent template in my template file, the error is not detected by ParseFiles() but by ExecuteTemplate(). One would expect parsing to detect any missing templates. Detecting such errors during parsing could also lead to performance improvements.

{{define &quot;test&quot;}}
&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt; test &lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;h1&gt; Hello, world!&lt;/h1&gt;
        {{template &quot;doesnotexist&quot;}}
    &lt;/body&gt;
&lt;/html&gt;
{{end}}

main.go

package main

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

func main() {
    t, err := template.ParseFiles(&quot;test.html&quot;)
    if err != nil {
        fmt.Printf(&quot;ParseFiles: %s\n&quot;, err)
        return
    }

    err = t.ExecuteTemplate(os.Stdout, &quot;test&quot;, nil)
    if err != nil {
        fmt.Printf(&quot;ExecuteTemplate: %s\n&quot;, err)
    }
}

10:46:30 $ go run main.go 
ExecuteTemplate: html/template:test.html:8:19: no such template &quot;doesnotexist&quot;
10:46:31 $ 

答案1

得分: 2

template.ParseFiles()方法不会报告缺失的模板,因为通常不会在单个步骤中解析所有模板,并且通过template.ParseFiles()报告缺失的模板将不允许这样做。

可以使用多个调用从多个源解析模板。

例如,如果在模板上调用Template.Parse()方法,可以向其添加更多模板:

_, err = t.Parse(`{{define "doesnotexist"}}the missing piece{{end}}`)
if err != nil {
    fmt.Printf("Parse failed: %v", err)
    return
}

上面的代码将添加缺失的部分,您的模板执行将成功并生成输出(在Go Playground上尝试):

<html>
    <head>
        <title> test </title>
    </head>
    <body>
        <h1> Hello, world!</h1>
        the missing piece
    </body>
</html>

进一步地,不要求解析和“呈现”所有模板可以提供优化的可能性。可能存在仅在管理员用户启动或使用应用程序时才需要的管理员页面,而“普通”用户从不使用这些页面。在这种情况下,您可以通过不必解析管理员页面(仅在管理员用户使用应用程序时)来加快启动速度并节省内存。

相关链接:https://stackoverflow.com/questions/41176355/go-template-name/41187671#41187671

英文:

template.ParseFiles() doesn't report missing templates, because often not all the templates are parsed in a single step, and reporting missing templates (by template.ParseFiles()) would not allow this.

It's possible to parse templates using multiple calls, from multiple sources.

For example if you call the Template.Parse() method or your template, you can add more templates to it:

_, err = t.Parse(`{{define &quot;doesnotexist&quot;}}the missing piece{{end}}`)
if err != nil {
	fmt.Printf(&quot;Parse failed: %v&quot;, err)
	return
}

The above code will add the missing piece, and your template execution will succeed and generate the output (try it on the Go Playground):

&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt; test &lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;h1&gt; Hello, world!&lt;/h1&gt;
        the missing piece
    &lt;/body&gt;
&lt;/html&gt;

Going further, not requiring all templates to be parsed and "presented" gives you optimization possibilities. It's possible there are admin pages which are never used by "normal" users, and are only required if an admin user starts or uses your app. In that case you can speed up startup and same memory by not having to parse admin pages (only when / if an admin user uses your app).

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

huangapple
  • 本文由 发表于 2022年4月12日 13:10:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/71837389.html
匿名

发表评论

匿名网友

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

确定