Reputation: 87
I'm trying to make a page in GO with Google App Engine which can show the content of an array with HTML parsing.
package hello
import (
"fmt"
"html/template"
"net/http"
)
func init() {
http.HandleFunc("/", root)
}
const TemplateHTML = `
<html>
<body>
<table width="700" border="1" align="center">
<tr>
<td>
{{range}} {{.name}} {{end}} {{range}} {{.Count}} {{end}}
</td>
</tr>
</table>
</body>
</html>
`
func root(w http.ResponseWriter, r *http.Request) {
type variables struct {
Name string
Count int
}
var data = []variables{
{"John", 25},
{"George", 35},
{"NoName", 27},
}
//name := variables{"Somebody", 25}
tmpl, err := template.New("i").Parse(TemplateHTML)
if err != nil {
fmt.Fprint(w, err)
}
err = tmpl.Execute(w, data)
if err != nil {
fmt.Fprint(w, err)
}
}
But I only get an Internal Server Error.
When I used err = tmpl.Execute(w, name)
(you can find 'name' in the comment in the code) it was okay.
Do you have any idea what can be the problem? I'm new in golang.
Thank you!
Upvotes: 4
Views: 1150
Reputation: 857
If template.Parse
returns an error, you can't use the other value it returns. You're trying to call tmpl.Execute
on a nil tmpl
if the template execution failed, which would lead to a panic.
Upvotes: 1
Reputation: 37279
Someone else will respond with a much more concise/accurate answer, but one simple way you can get your above example to work is to change your data
declaration to:
var data = []variables{
variables{"John", 25},
variables{"George", 35},
variables{"NoName", 27},
}
Here, you are making each element of the data
slice of type variables
, which will match the variables
type in the definition. I believe this was the main issue with your current version - the proper data type was not being supplied to data
. Then, you will just need to adjust your template so that your string looks as follows:
const TemplateHTML = `
<html>
<body>
<table width="700" border="1" align="center">
{{range .}}
<tr>
<td>{{.Name}}</td><td>{{.Count}}</td>
</tr>
{{end}}
</tr>
</table>
</body>
</html>
`
The key changes here were: making .Name
uppercase so it matches the property name and wrapping tr
in the {{range .}}
block so that a new row gets created for each entry (I assumed that's what you were looking for - if not, just make sure that range
encompasses whatever dynamic content you want).
Upvotes: 4