From a94b81f95793fb52bb0ddb5b49eda3dfb156297a Mon Sep 17 00:00:00 2001 From: Gregor Best <gbe@unobtanium.de> Date: Sun, 11 Apr 2021 23:24:42 +0200 Subject: [PATCH] Split handlers and templates --- main.go | 93 ++++----------------------------------------- templates/index.tpl | 25 ++++++------ 2 files changed, 18 insertions(+), 100 deletions(-) diff --git a/main.go b/main.go index a02a9ef..6c983c6 100644 --- a/main.go +++ b/main.go @@ -2,13 +2,9 @@ package main import ( "embed" - "errors" - "fmt" "html/template" - "io/ioutil" "log" "net/http" - "strconv" "github.com/jmoiron/sqlx" _ "modernc.org/sqlite" // Imported for side effects: registers DB driver @@ -16,13 +12,13 @@ import ( //go:embed templates/*.tpl var templateFS embed.FS -var templates = template.Must(template.ParseFS(templateFS, "templates/*.tpl")) +var templates = template.Must(template.ParseFS(templateFS, "templates/base.tpl", "templates/index.tpl")) //go:embed static/* var staticFS embed.FS func httpError(w http.ResponseWriter, msg string, err error, status int) { - log.Println(msg) + log.Println(msg+":", err) http.Error(w, msg+": "+err.Error(), status) } @@ -40,88 +36,13 @@ func main() { http.Handle("/static/", http.FileServer(http.FS(staticFS))) - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - log.Println("handling", r.Method, r.URL, "from", r.RemoteAddr) - - if r.Method == "GET" { - wines, err := ListWines(r.Context(), db) - if err != nil { - httpError(w, "can't list wines", err, http.StatusInternalServerError) - return - } - - w.Header().Add("content-type", "text/html") - - data := struct { - Wines []Vino - }{wines} - - err = templates.ExecuteTemplate(w, "index.tpl", data) - if err != nil { - log.Println("can't execute index template:", err) - } - - return - } - - if r.Method != "POST" { - httpError(w, "invalid method", errors.New(r.Method), http.StatusMethodNotAllowed) - return - } - - // TODO: load/store image - - name := r.FormValue("name") - if name == "" { - httpError(w, "bad name", errors.New("empty or missing"), http.StatusBadRequest) - return - } - - if len(name) > 80 { - httpError(w, "bad name", errors.New("name too long, max length is 80"), http.StatusBadRequest) - return - } - - ratingVal := r.FormValue("rating") - - var rating int - if ratingVal != "" { - rating, err = strconv.Atoi(ratingVal) - if err != nil { - httpError(w, "can't convert rating", err, http.StatusBadRequest) - return - } - } - - picFile, picHdr, err := r.FormFile("picture") - if err != nil { - httpError(w, "can't load picture file", err, http.StatusInternalServerError) - return - } - defer picFile.Close() - - log.Println("picture", picHdr.Size, picHdr.Header.Get("Content-Type")) - - picData, err := ioutil.ReadAll(picFile) - if err != nil { - httpError(w, "can't read picture file", err, http.StatusInternalServerError) - return - } - - vino := Vino{ - Name: name, - Rating: rating, - Picture: picData, - } + handler := Handler{ + db: db, + } - err = vino.Store(r.Context(), db) - if err != nil { - httpError(w, fmt.Sprintf("can't store wine %q", vino), err, http.StatusInternalServerError) - return - } + http.HandleFunc("/details/", handler.details) - http.Redirect(w, r, "/", http.StatusSeeOther) // TODO: Is this the correct status? - }) + http.HandleFunc("/", handler.index) const listenAddr = ":7878" diff --git a/templates/index.tpl b/templates/index.tpl index bd53485..3996bd4 100644 --- a/templates/index.tpl +++ b/templates/index.tpl @@ -1,14 +1,8 @@ -<!doctype html5> -<html> -<head> - <title>In Vino Veritas</title> - <style type="text/css"> - span.todo { - background: red; - } - </style> -</head> -<body> +{{ template "base" . }} + +{{ define "title" }}Index{{ end }} + +{{ define "content" }} The DB contains {{ .Wines | len }} wine(s) right now: <form method="POST" enctype="multipart/form-data" action="/add"> @@ -23,10 +17,13 @@ <table> <tr><th>#</th><th>Name</th><th>Rating</th></tr> {{ range .Wines }} - <tr><td>{{ .ID }}</td><td>{{ .Name }}</td><td>{{ .Rating }}</td></tr> + <tr> + <td>{{ .ID }}</td> + <td><a href="/details/{{ .ID }}">{{ .Name }}</a></td> + <td>{{ .Rating }}</td> + </tr> {{ end }} </table> <p>And a bit of foo.</p> -</body> -</html> \ No newline at end of file +{{ end }} \ No newline at end of file -- GitLab