aboutsummaryrefslogtreecommitdiffstats
path: root/internal/web/routes.go
diff options
context:
space:
mode:
authorgrm <grm@eyesin.space>2026-09-12 19:47:28 +0300
committergrm <grm@eyesin.space>2026-09-12 19:47:28 +0300
commite974eb6f3feb06c8951f85c1d34161938905f807 (patch)
tree3bba878b6764e9d18519efd393d4e780eaabd81a /internal/web/routes.go
parentdd13e4b73a105ee416b6cfd8eb19b217622c0031 (diff)
downloadblogspace-e974eb6f3feb06c8951f85c1d34161938905f807.tar.gz
blogspace-e974eb6f3feb06c8951f85c1d34161938905f807.tar.bz2
blogspace-e974eb6f3feb06c8951f85c1d34161938905f807.zip
Add a favicon and rework the Design page
Blogs had no icon at all, and browsers probing /favicon.ico ended up rendering the 404 page. Ship a default paper & ink icon (svg + png) and let each blog replace it from the Design page; /favicon.ico now serves the default or redirects to the blog's own image. ICO uploads accepted. The Design page gains colour schemes, reset to defaults, thumbnail image pickers, jump links and a sticky save bar, plus new options: heading font, link underline/hover, content box style and padding, header image height, post dates and format, footer RSS toggle, menu alignment/style/hover and sidebar width. The Menu card picks the position with illustrated tiles and shows only the options that apply to it, using CSS :checked rules rather than JavaScript. All new defaults reproduce the previous look, so existing blogs are unchanged until edited. Theme is jsonb, so no migration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'internal/web/routes.go')
-rw-r--r--internal/web/routes.go4
1 files changed, 4 insertions, 0 deletions
diff --git a/internal/web/routes.go b/internal/web/routes.go
index bd39a18..84b19a6 100644
--- a/internal/web/routes.go
+++ b/internal/web/routes.go
@@ -48,6 +48,8 @@ func (s *Server) rootRoutes() http.Handler {
m.HandleFunc("POST /b/{sub}/announcements/{id}/toggle", s.withBlog(s.handleSectionToggle))
m.HandleFunc("GET /b/{sub}/design", s.withBlog(s.handleDesignForm))
m.HandleFunc("POST /b/{sub}/design", s.withBlog(s.handleDesign))
+ m.HandleFunc("POST /b/{sub}/design/preset", s.withBlog(s.handleDesignPreset))
+ m.HandleFunc("POST /b/{sub}/design/reset", s.withBlog(s.handleDesignReset))
m.HandleFunc("GET /b/{sub}/images", s.withBlog(s.handleImages))
m.HandleFunc("POST /b/{sub}/images/upload", s.withBlog(s.handleImageUpload))
m.HandleFunc("POST /b/{sub}/images/{id}/delete", s.withBlog(s.handleImageDelete))
@@ -64,6 +66,7 @@ func (s *Server) rootRoutes() http.Handler {
m.HandleFunc("GET /media/{id}", s.handleMedia)
m.Handle("GET /static/{file}", s.staticHandler())
+ m.HandleFunc("GET /favicon.ico", s.hostBlog(s.handleFavicon))
// The root domain also serves the superadmin's blog. Literal routes above win
// over these wildcards; see reservedPageSlugs for the names that are shadowed.
s.blogRoutes(m, s.hostBlog)
@@ -84,6 +87,7 @@ func (s *Server) subdomainRoutes() http.Handler {
m.HandleFunc("GET /webadmin", s.handleWebadminRedirect)
m.HandleFunc("GET /media/{id}", s.handleMedia)
m.Handle("GET /static/{file}", s.staticHandler())
+ m.HandleFunc("GET /favicon.ico", s.hostBlog(s.handleFavicon))
s.blogRoutes(m, s.hostBlog)
return m
}