diff --git a/main.go b/main.go index b08145d5e32356cdbf57208f055b0905087fb60a..e6f9b578584a31b916b93efe944a0fd3f51e566b 100644 --- a/main.go +++ b/main.go @@ -37,13 +37,19 @@ type UserAgentResp struct { UserAgent string `json:"user-agent"` } -func index(w http.ResponseWriter, r *http.Request) { - t, err := template.ParseGlob("templates/*.html") - if err != nil { - http.Error(w, fmt.Sprintf("error parsing templates: %s", err), http.StatusInternalServerError) +// Index must be wrapped by the withTemplates middleware before it can be used +func index(w http.ResponseWriter, r *http.Request, t *template.Template) { + t = t.Lookup("index.html") + if t == nil { + http.Error(w, fmt.Sprintf("error looking up index.html"), http.StatusInternalServerError) return } - t = t.Lookup("index.html") + t.Execute(w, nil) +} + +// FormsPost must be wrapped by withTemplates middleware before it can be used +func formsPost(w http.ResponseWriter, r *http.Request, t *template.Template) { + t = t.Lookup("forms-post.html") if t == nil { http.Error(w, fmt.Sprintf("error looking up index.html"), http.StatusInternalServerError) return @@ -83,7 +89,9 @@ func headers(w http.ResponseWriter, r *http.Request) { func app() http.Handler { h := http.NewServeMux() - h.HandleFunc("/", methods(index, "GET")) + templateWrapper := withTemplates("templates/*.html") + h.HandleFunc("/", methods(templateWrapper(index), "GET")) + h.HandleFunc("/forms/post", methods(templateWrapper(formsPost), "GET")) h.HandleFunc("/get", methods(get, "GET")) h.HandleFunc("/ip", ip) h.HandleFunc("/user-agent", userAgent) diff --git a/main_test.go b/main_test.go index 1baf1a9a603abd6036761a63753fde0ed3fb430f..327bedbbdbf31265885d899e8d7495827c8bc830 100644 --- a/main_test.go +++ b/main_test.go @@ -19,6 +19,16 @@ func TestIndex(t *testing.T) { } } +func TestFormsPost(t *testing.T) { + r, _ := http.NewRequest("GET", "/forms/post", nil) + w := httptest.NewRecorder() + app().ServeHTTP(w, r) + + if !strings.Contains(w.Body.String(), `<form method="post" action="/post">`) { + t.Fatalf("expected <form> in body") + } +} + func TestGet__Basic(t *testing.T) { r, _ := http.NewRequest("GET", "/get", nil) r.Host = "localhost" diff --git a/middleware.go b/middleware.go index dc0708ca1a4295b777f19cbec521caaddf2ed785..e857f1997b519ceff1419525d010d9d334bd2874 100644 --- a/middleware.go +++ b/middleware.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "html/template" "log" "net/http" ) @@ -50,3 +51,19 @@ func methods(h http.HandlerFunc, methods ...string) http.HandlerFunc { h.ServeHTTP(w, r) } } + +// Simplify function signatures below +type templateHandlerFunc func(http.ResponseWriter, *http.Request, *template.Template) + +func withTemplates(path string) func(templateHandlerFunc) http.HandlerFunc { + t, err := template.ParseGlob(path) + if err != nil { + log.Fatalf("error parsing templates: %s", err) + } + + return func(handler templateHandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + handler(w, r, t) + } + } +} diff --git a/templates/forms-post.html b/templates/forms-post.html new file mode 100644 index 0000000000000000000000000000000000000000..e79dffd3216af510ac4c6f651a2006ea5d8be575 --- /dev/null +++ b/templates/forms-post.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> + <head> + </head> + <body> + <!-- Example form from HTML5 spec http://www.w3.org/TR/html5/forms.html#writing-a-form's-user-interface --> + <form method="post" action="/post"> + <p><label>Customer name: <input name="custname"></label></p> + <p><label>Telephone: <input type=tel name="custtel"></label></p> + <p><label>E-mail address: <input type=email name="custemail"></label></p> + <fieldset> + <legend> Pizza Size </legend> + <p><label> <input type=radio name=size value="small"> Small </label></p> + <p><label> <input type=radio name=size value="medium"> Medium </label></p> + <p><label> <input type=radio name=size value="large"> Large </label></p> + </fieldset> + <fieldset> + <legend> Pizza Toppings </legend> + <p><label> <input type=checkbox name="topping" value="bacon"> Bacon </label></p> + <p><label> <input type=checkbox name="topping" value="cheese"> Extra Cheese </label></p> + <p><label> <input type=checkbox name="topping" value="onion"> Onion </label></p> + <p><label> <input type=checkbox name="topping" value="mushroom"> Mushroom </label></p> + </fieldset> + <p><label>Preferred delivery time: <input type=time min="11:00" max="21:00" step="900" name="delivery"></label></p> + <p><label>Delivery instructions: <textarea name="comments"></textarea></label></p> + <p><button>Submit order</button></p> + </form> + </body> +</html>