// Guestbook -- main (starter). This file is finished. Finish // guestbook/guestbook.go and templates/home.html. // // Run from this folder, because the template and the data file are relative to // it: // cd projects/06-guestbook/starter // go run . package main import ( "bytes" "fmt" "html/template" "net/http" "guestbookapp/guestbook" ) const templateFile = "templates/home.html" const dataFile = "messages.json" // homeData is everything the template needs. type homeData struct { Error string Name string Text string Messages []guestbook.Message } var homeTemplate *template.Template var book *guestbook.Book // showHome builds the page in memory, and sends it only if that worked. func showHome(w http.ResponseWriter, status int, data homeData) { data.Messages = book.Messages() var page bytes.Buffer err := homeTemplate.Execute(&page, data) if err != nil { fmt.Println("Template error:", err) http.Error(w, "The page could not be built.", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") w.WriteHeader(status) page.WriteTo(w) } func handleHome(w http.ResponseWriter, r *http.Request) { showHome(w, http.StatusOK, homeData{}) } func handleAdd(w http.ResponseWriter, r *http.Request) { name := r.FormValue("name") text := r.FormValue("text") message, err := guestbook.NewMessage(name, text) if err != nil { // Show the form again, with what the visitor typed. data := homeData{Error: err.Error(), Name: name, Text: text} showHome(w, http.StatusBadRequest, data) return } err = book.Add(message) if err != nil { fmt.Println("Save error:", err) http.Error(w, "The message could not be saved.", http.StatusInternalServerError) return } http.Redirect(w, r, "/", http.StatusSeeOther) } func main() { parsed, err := template.ParseFiles(templateFile) if err != nil { fmt.Println("Could not read the template:", err) fmt.Println("Run this program from its own folder, and check the template.") return } homeTemplate = parsed opened, err := guestbook.Open(dataFile) if err != nil { fmt.Println("Could not load the messages:", err) fmt.Println("Fix or remove the file, then start the server again.") return } book = opened http.HandleFunc("GET /{$}", handleHome) http.HandleFunc("POST /messages", handleAdd) fmt.Println("Guestbook running at http://localhost:8080") fmt.Println("Press Ctrl+C to stop it.") err = http.ListenAndServe("localhost:8080", nil) if err != nil { fmt.Println("Server stopped:", err) } }