go – 调用 “html/template” 时参数不足。必须

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

go - Not enough arguments in call to "html/template".Must

问题

我在Golang中编写了一个包装函数,用于从多个文件中渲染模板,代码如下:

func RenderTemplate(w http.ResponseWriter, data interface{}, tmpl... string) {
    cwd, _ := os.Getwd()
    for _,file:=range tmpl{
        file=filepath.Join(cwd,"./view/"+file+".html")
    }
    t, err := template.ParseFiles(tmpl...)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    templates:=template.Must(t)
    err = templates.Execute(w, data)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

当我从main函数运行服务器时,控制台会抛出一个错误:

not enough arguments in call to "html/template".Must

如果我这样写:

templates,err:=template.Must(t)

它也会抛出相同的错误,还有:

assignment count mismatch: 2 = 1

我打算将此函数用作服务器中的路由处理程序:

func IndexHandler(w http.ResponseWriter, r *http.Request) {
    files:=[]string{"base","index"}
    util.RenderTemplate(w, nil, files...)
}

index.html通过模板嵌套扩展自base.html

base.html模板:

{{define "base"}}
<!DOCTYPE html>
<html>
<head>
    <meta charget="utf-8">
    <title>{{template "title" .}}</title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
    <script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="/js/isotope.pkgd.min.js"></script>
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
    <link rel="stylesheet" type="text/css" href="/css/style.css">
</head>
<body>
    {{template "index" .}}
</body>
</html>
{{end}}

以及index.html模板:

<!DOCTYPE html>
<html>
{{define "title"}}Homepage{{end}}
<body>
    {{define "index"}}
    <div class="wrapper">
        <div class="page-content">
            <div class="container">
                <div class="left">
                    <img src="../public/images/img_landing_page_mac.png">
                </div>
                <div class="right">
                    <h2 style="font-size: 33px; letter-spacing: 5px">Organize <br>Modern Knowledge<br> for Mankind</h2>
                    <p style="font-size: 20px;margin-top: 35px;letter-spacing: 4px">Consume, Colect and Revisit <br>Knowledge at Your Fingertips</p>
                    <a href="#" style="margin-top: 80px;display: inline-block;margin-left: -17px"><img src="../public/images/btn_get_chrome.png"></a>
                </div>
            </div>
        </div>
    </div>
    {{end}}
</body>
</html>

我有什么遗漏吗?我检查了"html/template".Must的原型,但不明白发生了什么。

英文:

I write a wrapper function in Golang for rendering template from multiple files like this:

func RenderTemplate(w http.ResponseWriter, data interface{}, tmpl... string) {
    cwd, _ := os.Getwd()
    for _,file:=range tmpl{
        file=filepath.Join(cwd,&quot;./view/&quot;+file+&quot;.html&quot;)
    }
    t, err := template.ParseFiles(tmpl...)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    templates:=template.Must(t)
    err = templates.Execute(w, data)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

When I run server from main function, the console throws an error:

not enough arguments in call to &quot;html/template&quot;.Must

If I write like this:

templates,err:=template.Must(t)

It also throws the same error, plus:

assignment count mismatch: 2 = 1

I intend to use this function for a route handler in server:

func IndexHandler(w http.ResponseWriter, r *http.Request) {
	files:=[]string{&quot;base&quot;,&quot;index&quot;}
	util.RenderTemplate(w, nil, files...)
}

index.html extends from base.html using template nesting

base.html template:

{{define &quot;base&quot;}}
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta charget=&quot;utf-8&quot;&gt;
	&lt;title&gt;{{template &quot;title&quot;.}}&lt;/title&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;https://code.jquery.com/jquery-2.2.0.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;/js/isotope.pkgd.min.js&quot;&gt;&lt;/script&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css&quot;&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css&quot;&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/css/style.css&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
	{{template &quot;index&quot;.}}
&lt;/body&gt;
&lt;/html&gt;
{{end}}

And index.html template:

&lt;!DOCTYPE html&gt;
&lt;html&gt;
{{define &quot;title&quot;}}Homepage{{end}}
&lt;body&gt;
	{{define &quot;index&quot;}}
	&lt;div class=&quot;wrapper&quot;&gt;
		&lt;div class=&quot;page-content&quot;&gt;
			&lt;div class=&quot;container&quot;&gt;
				&lt;div class=&quot;left&quot;&gt;
					&lt;img src=&quot;../public/images/img_landing_page_mac.png&quot;&gt;
				&lt;/div&gt;
				&lt;div class=&quot;right&quot;&gt;
					&lt;h2 style=&quot;font-size: 33px; letter-spacing: 5px&quot;&gt;Organize &lt;br&gt;Modern Knowledge&lt;br&gt; for Mankind&lt;/h2&gt;
					&lt;p style=&quot;font-size: 20px;margin-top: 35px;letter-spacing: 4px&quot;&gt;Consume, Colect and Revisit &lt;br&gt;Knowledge at Your Fingertips&lt;/p&gt;
					&lt;a href=&quot;#&quot; style=&quot;margin-top: 80px;display: inline-block;margin-left: -17px&quot;&gt;&lt;img src=&quot;../public/images/btn_get_chrome.png&quot;&gt;&lt;/a&gt;
				&lt;/div&gt;
			&lt;/div&gt;
		&lt;/div&gt;
	&lt;/div&gt;
	{{end}}
&lt;/body&gt;
&lt;/html&gt;

Did I miss something? I checked the prototype of &quot;html/template&quot;.Must and didn't get what happened

答案1

得分: 1

你不需要调用ParseFiles和Must,你可以调用其中一个。

func RenderTemplate(w http.ResponseWriter, data interface{}, tmpl... string) {
    cwd, _ := os.Getwd()
    for _,file:=range tmpl{
        file=filepath.Join(cwd,"./view/"+file+".html")
    }
    t, err := template.ParseFiles(tmpl...)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    err = t.Execute(w, data)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

我相信上面的函数应该可以满足你的需求...

英文:

You do not need to call ParseFiles and Must, you can call one or the other

func RenderTemplate(w http.ResponseWriter, data interface{}, tmpl... string) {
    cwd, _ := os.Getwd()
    for _,file:=range tmpl{
        file=filepath.Join(cwd,&quot;./view/&quot;+file+&quot;.html&quot;)
    }
    t, err := template.ParseFiles(tmpl...)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    err = t.Execute(w, data)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

I believe the func above should do what you want...

答案2

得分: 1

template.Must()的签名如下:

func Must(t *Template, err error) *Template 

Must()的参数“巧合地”与ParseFiles()ParseGlob()的返回值相同,因此您可以在Must()内部使用这些函数,并且如果错误非空,则会引发panic。因此,您可以这样写:

t := template.Must(template.ParseFiles(....))

而不必担心错误检查。这只是一个方便函数,类似于标准库中的所有其他Must()函数,例如regexp.MustCompile()

Must()的实现很简单:

func Must(t *Template, err error) *Template {
	if err != nil {
			panic(err)
	}
	return t
}

请参阅https://golang.org/src/text/template/helper.go?s=576:619#L11

英文:

template.Must() has this signature:

func Must(t *Template, err error) *Template 

the arguments to Must() are "by coincidence" the same as the return values to ParseFiles() and ParseGlob() so you can use those functions inside Must() and have the effect that it panics, if the error is non-nil. So you can say

t := template.Must(template.ParseFiles(....))

and don't care about the error checking. This is merely a convenience function, similar to all other Must() functions throughout the standard library, such as regexp.MustCompile().

The implementation of Must() is straightforward:

func Must(t *Template, err error) *Template {
	if err != nil {
			panic(err)
	}
	return t
}

See https://golang.org/src/text/template/helper.go?s=576:619#L11

huangapple
  • 本文由 发表于 2016年3月10日 07:27:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/35904722.html
匿名

发表评论

匿名网友

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

确定