valaki
valaki

Reputation: 87

How to parse HTML template in GO, Google App Engine

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

Answers (2)

dsymonds
dsymonds

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

RocketDonkey
RocketDonkey

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

Related Questions