I am trying to display the contents of a slice on a page. Displaying the templates with static text works. As soon as I try and range over the slice sent to ExTpl()
, I get an EOF error.
type Miner struct {
IP string `bson:"ip"`
Port int32 `bson:"port"`
FailCount int `bson:"failcount"`
}
type (
MinerController struct {
Session *mgo.Session
}
)
func ExTpl(w http.ResponseWriter, data []Miner) {
t, _ := template.ParseFiles("templates/header.tmpl", "templates/footer.tmpl", "templates/data.tmpl")
t.ExecuteTemplate(w, "data", data)
}
func FilterMiners(c *mgo.Collection, key, value string, limit int) ([]Miner, int, error) {
var results []Miner
query := bson.M{key: value}
if len(key) == 0 {
query = nil
}
err := c.Find(query).Limit(limit).All(&results)
if err != nil {
return results, 0,errors.New("error retrieving hosts")
}
return results, len(results), nil
}
func (mc MinerController) GetSpecificMiners(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
l, err := strconv.Atoi(vars["limit"])
if err != nil {
l = 0
}
collection := Collection("miners", "NASty", mc.Session)
fleet, _ , _ := FilterMiners(collection, vars["key"], vars["value"], l)
ExTpl(w, fleet)
}
Here are the templates in question:
header.tmpl
{{define "header"}}
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
</head>
<body>
{{end}}
data.tmpl
{{define "data"}}
{{template "header"}}
{{range .}}
{{.IP}}
{{template "footer"}}
{{end}}
footer.tmpl
{{define "footer"}}
</body>
</html>
{{end}}
When I run this, I get the following error:
2017/10/27 12:24:56 http: panic serving [::1]:50252: template: data.tmpl:6: unexpected EOF
goroutine 49 [running]:
net/http.(*conn).serve.func1(0xc042138000)
C:/Go/src/net/http/server.go:1721 +0xd7
panic(0x7abbc0, 0xc042170360)
C:/Go/src/runtime/panic.go:489 +0x2dd
git.REDACTED.duckdns.org/REDACTED/RESTingMongo/controllers.ExTpl(0x9b7820, 0xc04211c460, 0xc042172000, 0x2, 0x2)
D:/_projects/Go/src/git.REDACTED.duckdns.org/REDACTED/RESTingMongo/controllers/handlers.go:25 +0x84
git.REDACTED.duckdns.org/REDACTED/RESTingMongo/controllers.MinerController.GetSpecificMiners(0xc04203b040, 0x9b7820, 0xc04211c460, 0xc0420f6600)
D:/_projects/Go/src/git.REDACTED.duckdns.org/REDACTED/RESTingMongo/controllers/miners.go:74 +0x2b9
git.REDACTED.duckdns.org/REDACTED/RESTingMongo/controllers.(MinerController).GetSpecificMiners-fm(0x9b7820, 0xc04211c460, 0xc0420f6600)
D:/_projects/Go/src/git.REDACTED.duckdns.org/REDACTED/RESTingMongo/routes/routes.go:33 +0x55
net/http.HandlerFunc.ServeHTTP(0xc04203f210, 0x9b7820, 0xc04211c460, 0xc0420f6600)
C:/Go/src/net/http/server.go:1942 +0x4b
git.REDACTED.duckdns.org/REDACTED/RESTingMongo/routes.Logger.func1(0x9b7820, 0xc04211c460, 0xc0420f6600)
D:/_projects/Go/src/git.REDACTED.duckdns.org/REDACTED/RESTingMongo/routes/handlers.go:12 +0x18d
net/http.HandlerFunc.ServeHTTP(0xc0420467c0, 0x9b7820, 0xc04211c460, 0xc0420f6600)
C:/Go/src/net/http/server.go:1942 +0x4b
github.com/gorilla/mux.(*Router).ServeHTTP(0xc04203c420, 0x9b7820, 0xc04211c460, 0xc0420f6600)
D:/_projects/Go/src/github.com/gorilla/mux/mux.go:133 +0x108
net/http.serverHandler.ServeHTTP(0xc04208e2c0, 0x9b7820, 0xc04211c460, 0xc042116100)
C:/Go/src/net/http/server.go:2568 +0x99
net/http.(*conn).serve(0xc042138000, 0x9b7fe0, 0xc042104280)
C:/Go/src/net/http/server.go:1825 +0x619
created by net/http.(*Server).Serve
C:/Go/src/net/http/server.go:2668 +0x2d5
I am not sure what is going on, since all of my templates have the correct format, and the Miner
struct contains an IP
field, which I should be able to access in the range loop with .IP
.
Your data
template definition is invalid. Both the {{define}}
and {{range}}
actions need a closing {{end}}
, so it should be:
{{define "data"}}
{{template "header"}}
{{range .}}
{{.IP}}
{{end}}
{{template "footer"}}
{{end}}
Some advices:
Never omit errors, always check them and the least you can do is print them (you omit errors returned by template.ParseFiles()
and FilterMiners()
).
Never parse templates in HTTP handlers, for details see: It takes too much time when using "template" package to generate a dynamic web page to client in golang
From what I can see you have an {{end}} missing in data.tmpl.
{{define "data"}}
{{template "header"}}
{{range .}}
{{.IP}}
{{template "footer"}}
{{end}}
should be:
{{define "data"}}
{{template "header"}}
{{range .}}
{{.IP}}
{{end}}
{{template "footer"}}
{{end}}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With