Da ich mich gerade in die Programmiersprache GO einarbeite, habe ich eine kleine Web-Anwendung erstellt. Die Seiten werden mit der GO-Templateengine erstellt und man kann den Vor- und Nachnamen einer Person Eingeben und Anzeigen lassen. Das ist natürlich nicht viel mehr als ein Hello-World, aber irgendwo muss man ja anfangen.
main.go
package main
import (
"fmt"
"html/template"
"io/ioutil"
"log"
"net/http"
"os"
"sync"
)
//var templates *template.Template
var person Person
func init() {
/* log.Print("init start")
templates = template.Must(template.ParseGlob("templates/*.html"))
log.Printf("init end, template=%v", templates)
*/
person.FirstName = "Max"
person.LastName = "Mustermann"
}
func main() {
http.HandleFunc("/", viewHandler)
http.ListenAndServe(":8080", nil)
}
func viewHandler(w http.ResponseWriter, r *http.Request) {
url := r.URL.Path
log.Printf("Path: %v", url)
switch url {
case "/":
url = "/index"
case "/sendperson":
url = "/showperson"
log.Printf("Method: %v", r.Method)
updatePerson(r.FormValue("firstname"), r.FormValue("lastname"))
log.Printf("FirstName: %v, LastName: %v", person.FirstName, person.LastName)
http.Redirect(w, r, "/showperson", 301)
}
loadFile := fmt.Sprintf("templates%s.html", url)
log.Printf("Template: %v", loadFile)
layout, _ := template.ParseFiles("_layout.html")
tmpl, _ := layout.Clone()
f, err := os.Open(loadFile)
if err != nil {
log.Println(err)
http.Redirect(w, r, "/", http.StatusNotFound)
}
content, _ := ioutil.ReadAll(f)
f.Close()
tmpl.Parse(string(content))
//templates.ExecuteTemplate(w, "template.html", person)
tmpl.Execute(w, person)
}
type Person struct {
FirstName string
LastName string
}
func updatePerson(firstname, lastname string) {
var mutex sync.Mutex
mutex.Lock()
person.FirstName = firstname
person.LastName = lastname
mutex.Unlock()
}
_layout.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
{{template "header"}}
</head>
<body>
{{template "body" .}}
</body>
</html>
templates/index.html
{{define "body"}}
<h1>Edit Person</h1>
<form action="sendperson" id="person" method="POST">
FirstName: {{.FirstName}}<br>
LastName: {{.LastName}}<br>
<label for="firstname">FirstName</label>
<input type="text" name="firstname" id="firstname" maxlength="40" value="{{.FirstName}}">
<label for="lastname">LastName</label>
<input type="text" name="lastname" id="lastname" maxlength="40" value="{{.LastName}}">
<button type="reset">Eingaben zurücksetzen</button>
<button type="submit">Eingaben absenden</button>
</form>
{{end}}
{{define "header"}}{{end}}
templates/showperson.html
{{define "body"}}
<h1>Show Person</h1>
FirstName: {{.FirstName}}<br>
LastName: {{.LastName}}<br>
<a href="/">Edit</a>
{{end}}
{{define "header"}}{{end}}
Zu beachten ist, dass die Logik für die Templates “umgedreht” wurde. D.h. In das Layout wird die eigentliche Seite geladen. Normalerweise würde in der Seite ein Include für Header und Body etc. stehen …
Damit das funktioniert dürfen nicht alle Templates gemeinsam geladen werden, sondern für jede Seite zuerst das Layout dann der zugehörige “Seite” mit der “body”-Definition!