diff --git a/config/config.go b/config/config.go index a067f63..906ae13 100644 --- a/config/config.go +++ b/config/config.go @@ -4,28 +4,25 @@ import ( "strings" ) -var basePartials = []string{ - "views/baseof.html", - "views/_partials/head.html", - "views/_partials/header.html", - "views/_partials/footer.html", +var base = []string{ + "templates/baseof.html", + "templates/_partials/head.html", + "templates/_partials/header.html", + "templates/_partials/footer.html", } var ViewMap = map[string][]string{ - "index-page": append(basePartials, "views/index.html", "views/index-page.html"), - "login-page": append(basePartials, "views/login.html", "views/login-page.html"), - "dashboard-page": append(basePartials, "views/dashboard.html", "views/dashboard-page.html", "views/control-madre.html"), - "suppliers-page": append(basePartials, "views/suppliers.html", "views/suppliers-page.html"), - "fse-page": append(basePartials, "views/fse.html", "views/fse-page.html"), - "panel-page": append(basePartials, "views/panel.html", "views/panel-page.html", "views/users.html", "views/user.html"), + "login-page": append( + base, + "templates/login.html", + "templates/login-page.html", + ), - "login": {"views/login.html"}, - "dashboard": {"views/dashboard.html", "views/control-madre.html"}, - "control-madre": {"views/control-madre.html"}, - "user": {"views/user.html"}, - "users": {"views/users.html", "views/user.html"}, - "success-button": {"views/success-button.html"}, - "fail-button": {"views/fail-button.html"}, + "index-page": append( + base, + "templates/index.html", + "templates/index-page.html", + ), } var FuncMap = map[string]any{ diff --git a/handlers/sampleHandlers.go b/handlers/sampleHandlers.go new file mode 100644 index 0000000..82ed820 --- /dev/null +++ b/handlers/sampleHandlers.go @@ -0,0 +1,19 @@ +package handlers + +import ( + "net/http" + + "git.tavo.one/tavo/axiom/views" +) + +func (h *Handler) SampleIndex(w http.ResponseWriter, r *http.Request) { + views.RenderHTML(w, r, "index-page", nil) +} + +func (h *Handler) SampleLoginPage(w http.ResponseWriter, r *http.Request) { + views.RenderHTML(w, r, "login-page", nil) +} + +func (h *Handler) SampleLoginForm(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("Authentication complete!")) +} diff --git a/handlers/sampleIndex.go b/handlers/sampleIndex.go deleted file mode 100644 index de85199..0000000 --- a/handlers/sampleIndex.go +++ /dev/null @@ -1,9 +0,0 @@ -package handlers - -import ( - "net/http" -) - -func (h *Handler) SampleIndex(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("Hello from Index!")) -} diff --git a/main.go b/main.go index b8b07e0..7d4d3c5 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "log" + "io/fs" "net/http" "os" "os/signal" @@ -15,10 +16,10 @@ import ( "git.tavo.one/tavo/axiom/views" ) -// //go:embed static/* -// var publicFS embed.FS +//go:embed static/* +var publicFS embed.FS -//go:embed views/* +//go:embed templates/* var viewFS embed.FS func init() { @@ -62,8 +63,17 @@ func main() { } handler := handlers.New(handlerConfig) - router := http.NewServeMux() - router.HandleFunc("GET /", handler.SampleIndex) + router := routes(handler) + + staticFiles, err := fs.Sub(publicFS, "static") + if err != nil { + log.Fatalf("failed to create static files filesystem: %v", err) + } + + router.Handle( + "GET /s/", + http.StripPrefix("/s/", http.FileServer(http.FS(staticFiles))), + ) stop := make(chan os.Signal, 1) signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM) diff --git a/middleware/example.go b/middleware/example.go new file mode 100644 index 0000000..f358cd4 --- /dev/null +++ b/middleware/example.go @@ -0,0 +1,13 @@ +package middleware + +import ( + "log" + "net/http" +) + +func AuthCheck(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + log.Printf("Sample Authenticated request: %s %s", r.Method, r.URL.Path) + next.ServeHTTP(w, r) + }) +} diff --git a/middleware/middleware.go b/middleware/middleware.go new file mode 100644 index 0000000..bcb5a96 --- /dev/null +++ b/middleware/middleware.go @@ -0,0 +1,18 @@ +package middleware + +import "net/http" + +type Middleware func(http.Handler) http.Handler + +func Stack(xs ...Middleware) Middleware { + return func(next http.Handler) http.Handler { + for i := len(xs) - 1; i >= 0; i-- { + next = xs[i](next) + } + return next + } +} + +func With(mw Middleware, h http.HandlerFunc) http.Handler { + return mw(h) +} diff --git a/routes.go b/routes.go new file mode 100644 index 0000000..f01cf82 --- /dev/null +++ b/routes.go @@ -0,0 +1,33 @@ +package main + +import ( + "net/http" + + "git.tavo.one/tavo/axiom/handlers" + "git.tavo.one/tavo/axiom/middleware" +) + +func routes(handler *handlers.Handler) *http.ServeMux { + router := http.NewServeMux() + + protectedStack := middleware.Stack( + middleware.AuthCheck, + ) + + router.HandleFunc( + "GET /", + handler.SampleIndex, + ) + + router.HandleFunc( + "GET /login", + handler.SampleLoginPage, + ) + + router.Handle( + "POST /login", + middleware.With(protectedStack, handler.SampleLoginForm), + ) + + return router +} diff --git a/scripts/minify.go b/scripts/minify.go index ee772d9..86b3e09 100644 --- a/scripts/minify.go +++ b/scripts/minify.go @@ -1,7 +1,6 @@ package main import ( - "bytes" "flag" "fmt" "io/fs" @@ -68,7 +67,6 @@ func main() { return fmt.Errorf("failed to minify %s: %w", path, err) } - fmt.Printf("Minified %s -> %s\n", path, dstPath) return nil }) diff --git a/views/views.go b/views/views.go index 5f474e6..d17de48 100644 --- a/views/views.go +++ b/views/views.go @@ -2,6 +2,7 @@ package views import ( "bytes" + "compress/gzip" "embed" "fmt" "html/template" @@ -57,20 +58,29 @@ func initTemplates(viewFS embed.FS, viewMap map[string][]string, funcMap map[str return cache, nil } -func RenderHTML(w http.ResponseWriter, name string, data any) error { +func RenderHTML(w http.ResponseWriter, r *http.Request, name string, data any) error { tmpl, ok := TemplateCache[name] if !ok { http.Error(w, "template not found: "+name, http.StatusNotFound) return fmt.Errorf("template %q not found", name) } - w.Header().Set("Content-Type", "text/html; charset=utf-8") - var buf bytes.Buffer if err := tmpl.ExecuteTemplate(&buf, tmpl.Name(), data); err != nil { return fmt.Errorf("failed to execute template %q: %w", name, err) } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.Header().Set("Vary", "Accept-Encoding") + + if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") { + w.Header().Set("Content-Encoding", "gzip") + gz := gzip.NewWriter(w) + defer gz.Close() + _, err := io.Copy(gz, &buf) + return err + } + _, err := io.Copy(w, &buf) return err }