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  }