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,"./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)
}
}
When I run server from main
function, the console throws an error:
not enough arguments in call to "html/template".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{"base","index"}
util.RenderTemplate(w, nil, files...)
}
index.html
extends from base.html
using template nesting
base.html
template:
{{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}}
And index.html
template:
<!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>
Did I miss something? I checked the prototype of "html/template".Must
and didn't get what happened
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,"./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)
}
}
I believe the func above should do what you want...
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