Pinterest-style visual bookmarking app with: - URL metadata extraction (OG/Twitter meta, oEmbed fallback) - Image caching in Postgres with 480px thumbnails - Multi-tag filtering with Ctrl/Cmd for OR mode - Fuzzy tag suggestions and inline tag editing - Browser console auth() with first-use password setup - Brutalist UI with Commit Mono font and Pico CSS - Light/dark mode via browser preference
42 lines
994 B
Go
42 lines
994 B
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
)
|
|
|
|
// Router wraps http.ServeMux and automatically injects RequestContext into handlers.
|
|
type Router struct {
|
|
mux *http.ServeMux
|
|
rc *RequestContext
|
|
}
|
|
|
|
func NewRouter(rc *RequestContext) *Router {
|
|
return &Router{
|
|
mux: http.NewServeMux(),
|
|
rc: rc,
|
|
}
|
|
}
|
|
|
|
// Handle registers a handler that returns an error.
|
|
// The RequestContext is automatically injected and error handling is applied.
|
|
func (rt *Router) Handle(pattern string, h Handler) {
|
|
rt.mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
|
rc := &RequestContext{
|
|
DB: rt.rc.DB,
|
|
Logger: rt.rc.Logger,
|
|
TmplCache: rt.rc.TmplCache,
|
|
}
|
|
|
|
handler := WithErrorHandling(rc, h)
|
|
handler(w, r)
|
|
})
|
|
}
|
|
|
|
// HandleStd registers a standard http.Handler (for static files, etc.)
|
|
func (rt *Router) HandleStd(pattern string, h http.Handler) {
|
|
rt.mux.Handle(pattern, h)
|
|
}
|
|
|
|
func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
rt.mux.ServeHTTP(w, r)
|
|
}
|