Gopherbw m

Meine erste kleine GO Webanwendung

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!

{{ message }}

{{ 'Comments are closed.' | trans }}