81 lines
1.5 KiB
Go
81 lines
1.5 KiB
Go
package httpapp
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"net/http"
|
|
"path/filepath"
|
|
"time"
|
|
)
|
|
|
|
type Config struct {
|
|
Addr string
|
|
TemplatesDir string
|
|
StaticDir string
|
|
}
|
|
|
|
type App struct {
|
|
cfg Config
|
|
tmpl *template.Template
|
|
mux *http.ServeMux
|
|
}
|
|
|
|
func New(cfg Config) (*App, error) {
|
|
if cfg.TemplatesDir == "" {
|
|
cfg.TemplatesDir = "web/templates"
|
|
}
|
|
if cfg.StaticDir == "" {
|
|
cfg.StaticDir = "web/static"
|
|
}
|
|
|
|
tmpl, err := parseTemplates(cfg.TemplatesDir)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
a := &App{
|
|
cfg: cfg,
|
|
tmpl: tmpl,
|
|
mux: http.NewServeMux(),
|
|
}
|
|
|
|
a.routes()
|
|
return a, nil
|
|
}
|
|
|
|
func (a *App) Router() http.Handler {
|
|
// Wrap the mux with basic middleware chain
|
|
return requestID(logging(a.mux))
|
|
}
|
|
|
|
func (a *App) routes() {
|
|
// Static
|
|
fs := http.FileServer(http.Dir(a.cfg.StaticDir))
|
|
a.mux.Handle("/static/", http.StripPrefix("/static/", fs))
|
|
|
|
// Core pages
|
|
a.mux.HandleFunc("/", a.handleDashboard)
|
|
|
|
// Health & metrics
|
|
a.mux.HandleFunc("/healthz", a.handleHealthz)
|
|
a.mux.HandleFunc("/metrics", a.handleMetrics)
|
|
}
|
|
|
|
func parseTemplates(dir string) (*template.Template, error) {
|
|
pattern := filepath.Join(dir, "*.html")
|
|
files, err := filepath.Glob(pattern)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(files) == 0 {
|
|
return nil, fmt.Errorf("no templates found at %s", pattern)
|
|
}
|
|
|
|
funcs := template.FuncMap{
|
|
"nowRFC3339": func() string { return time.Now().Format(time.RFC3339) },
|
|
}
|
|
|
|
t := template.New("root").Funcs(funcs)
|
|
return t.ParseFiles(files...)
|
|
}
|