github.com/scottcagno/storage@v1.8.0/cmd/web/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "github.com/scottcagno/storage/pkg/util" 6 "github.com/scottcagno/storage/pkg/web" 7 "github.com/scottcagno/storage/pkg/web/logging" 8 "html/template" 9 "log" 10 "math" 11 "math/rand" 12 "net/http" 13 "path/filepath" 14 "strings" 15 "time" 16 ) 17 18 const LISTENING_ADDR = ":8080" 19 20 func main() { 21 22 // initialize a logger 23 stdOut, stdErr := logging.NewDefaultLogger() 24 25 // get filepath for later 26 path, _ := util.GetFilepath() 27 28 // initialize a new multiplexer configuration 29 muxConf := &web.MuxConfig{ 30 StaticPath: filepath.Join(path, "data/static/"), 31 WithLogging: true, 32 StdOutLogger: stdOut, 33 StdErrLogger: stdErr, 34 } 35 36 // initialize new http multiplexer 37 mux := web.NewServeMux(muxConf) 38 39 // initialize a new template cache configuration 40 tmplConf := &web.TemplateConfig{ 41 StubsPattern: filepath.Join(path, "data/templates/*/*.html"), 42 TemplatePattern: filepath.Join(path, "data/templates/*.html"), 43 StdErrLogger: stdErr, 44 FuncMap: fm, 45 } 46 47 // initialize a new template cache instance 48 tc, err := web.NewTemplateCache(tmplConf) 49 if err != nil { 50 log.Panicln(err) 51 } 52 // add separate stubs 53 err = tc.AddSeparateStubs(tmplConf.StubsPattern) 54 if err != nil { 55 log.Panicln(err) 56 } 57 58 // setup routes and handlers 59 //mux.Get("", http.NotFoundHandler()) 60 mux.Get("/", http.RedirectHandler("/info", http.StatusTemporaryRedirect)) 61 mux.Get("/index", indexHandler(tc.Lookup("index.html"))) 62 63 mux.Get("/index2", index2Handler(tc.Lookup("index-two.html"))) 64 65 mux.Get("/home", homeHandler(tc.Lookup("home.html"))) 66 67 mux.Get("/login", loginHandler(tc.Lookup("login.html"))) 68 mux.Get("/post", postHandler(tc.Lookup("post.html"))) 69 mux.Get("/functest", funcTestHandler(tc.Lookup("func-test.html"))) 70 71 // OPTION #1 (passing the entire template cache) 72 mux.Get("/user", userHandler(tc)) 73 74 // OPTION #2 (passing the single template) 75 mux.Get("/user/2", user2Handler(tc.Lookup("user-model-02.html"))) 76 77 // OPTION #3 (also, just a different way of passing the single template) 78 user3 := tc.Lookup("user-model-03.html") 79 mux.Get("/user/3", user3Handler(user3)) 80 mux.Get("/templates", listTemplates(tc)) 81 82 mux.Get("/foo", tc.Handle("foo.html")) 83 mux.Get("/foo/data", tc.HandleWithData("foo.html", struct { 84 Data interface{} 85 }{ 86 Data: "THIS IS A TEST", 87 })) 88 89 util.HandleSignalInterrupt("Server started, listening on %s", LISTENING_ADDR) 90 stdErr.Panicln(http.ListenAndServe(LISTENING_ADDR, mux)) 91 } 92 93 var fm = template.FuncMap{ 94 "add": func(a, b int) int { 95 return a + b 96 }, 97 "mod": func(a, b int) int { 98 return a % b 99 }, 100 "rand": func(min, max int) int { 101 rand.Seed(time.Now().UnixNano()) 102 return rand.Intn(max-min+1) + min 103 }, 104 "log2": math.Log2, 105 "log": math.Log, 106 "love": func(name string) string { 107 return "I love you " + name 108 }, 109 "title": strings.ToTitle, 110 } 111 112 func PrintTemplates(name string, tc *web.TemplateCache) { 113 templs, defined := tc.Templates() 114 fmt.Printf("[%s]\n%s\n", name, defined) 115 for i, tmpl := range templs { 116 fmt.Printf("template[%d]=%q\n", i, tmpl.Name()) 117 } 118 } 119 120 func listTemplates(tc *web.TemplateCache) http.Handler { 121 fn := func(w http.ResponseWriter, r *http.Request) { 122 var s string 123 templs, defined := tc.Templates() 124 s += fmt.Sprintf("%s\n", defined) 125 for i, tmpl := range templs { 126 s += fmt.Sprintf("template[%d]=%q\n", i, tmpl.Name()) 127 } 128 fmt.Fprint(w, s) 129 return 130 } 131 return http.HandlerFunc(fn) 132 } 133 134 func indexHandler(t *template.Template) http.Handler { 135 fn := func(w http.ResponseWriter, r *http.Request) { 136 err := t.Execute(w, nil) 137 if err != nil { 138 code := http.StatusNotAcceptable 139 http.Error(w, http.StatusText(code), code) 140 return 141 } 142 return 143 } 144 return http.HandlerFunc(fn) 145 } 146 147 func index2Handler(t *template.Template) http.Handler { 148 fn := func(w http.ResponseWriter, r *http.Request) { 149 err := t.Execute(w, nil) 150 if err != nil { 151 code := http.StatusNotAcceptable 152 http.Error(w, http.StatusText(code), code) 153 return 154 } 155 return 156 } 157 return http.HandlerFunc(fn) 158 } 159 160 func homeHandler(t *template.Template) http.Handler { 161 fn := func(w http.ResponseWriter, r *http.Request) { 162 err := t.Execute(w, nil) 163 if err != nil { 164 code := http.StatusNotAcceptable 165 http.Error(w, http.StatusText(code), code) 166 return 167 } 168 return 169 } 170 return http.HandlerFunc(fn) 171 } 172 173 func loginHandler(t *template.Template) http.Handler { 174 fn := func(w http.ResponseWriter, r *http.Request) { 175 err := t.Execute(w, nil) 176 if err != nil { 177 code := http.StatusNotAcceptable 178 http.Error(w, http.StatusText(code), code) 179 return 180 } 181 return 182 } 183 return http.HandlerFunc(fn) 184 } 185 186 func postHandler(t *template.Template) http.Handler { 187 fn := func(w http.ResponseWriter, r *http.Request) { 188 err := t.Execute(w, nil) 189 if err != nil { 190 code := http.StatusNotAcceptable 191 http.Error(w, http.StatusText(code), code) 192 return 193 } 194 return 195 } 196 return http.HandlerFunc(fn) 197 } 198 199 func funcTestHandler(t *template.Template) http.Handler { 200 fn := func(w http.ResponseWriter, r *http.Request) { 201 err := t.Execute(w, nil) 202 if err != nil { 203 code := http.StatusNotAcceptable 204 http.Error(w, http.StatusText(code), code) 205 return 206 } 207 return 208 } 209 return http.HandlerFunc(fn) 210 } 211 212 func userHandler(t *web.TemplateCache) http.Handler { 213 user := map[string]interface{}{ 214 "ID": 34, 215 "Name": "Jon Doe", 216 "Email": "jdoe@ex.com", 217 "Password": "none", 218 "IsActive": true, 219 } 220 fn := func(w http.ResponseWriter, r *http.Request) { 221 t.Render(w, r, "user-model.html", struct { 222 User map[string]interface{} 223 }{ 224 User: user, 225 }) 226 return 227 } 228 return http.HandlerFunc(fn) 229 } 230 231 func user2Handler(t *template.Template) http.Handler { 232 user := map[string]interface{}{ 233 "ID": 36, 234 "Name": "Jane Doe (the explorer)", 235 "Email": "jdoe@ex.com", 236 "Password": "none", 237 "IsActive": true, 238 } 239 fn := func(w http.ResponseWriter, r *http.Request) { 240 err := t.Execute(w, struct { 241 User map[string]interface{} 242 }{ 243 User: user, 244 }) 245 if err != nil { 246 code := http.StatusNotAcceptable 247 http.Error(w, http.StatusText(code), code) 248 return 249 } 250 return 251 } 252 return http.HandlerFunc(fn) 253 } 254 255 func user3Handler(t *template.Template) http.Handler { 256 user := map[string]interface{}{ 257 "ID": 86, 258 "Name": "Some Rando", 259 "Email": "srando@example.com", 260 "Password": "foobar", 261 "IsActive": true, 262 } 263 fn := func(w http.ResponseWriter, r *http.Request) { 264 err := t.Execute(w, struct { 265 User map[string]interface{} 266 }{ 267 User: user, 268 }) 269 if err != nil { 270 code := http.StatusNotAcceptable 271 http.Error(w, http.StatusText(code), code) 272 return 273 } 274 return 275 } 276 return http.HandlerFunc(fn) 277 }