aboutsummaryrefslogtreecommitdiffstats
path: root/internal/web/handlers_design.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/web/handlers_design.go')
-rw-r--r--internal/web/handlers_design.go37
1 files changed, 23 insertions, 14 deletions
diff --git a/internal/web/handlers_design.go b/internal/web/handlers_design.go
index 9f98e9e..7424eca 100644
--- a/internal/web/handlers_design.go
+++ b/internal/web/handlers_design.go
@@ -10,6 +10,7 @@ import (
"path/filepath"
"strconv"
"strings"
+ "time"
"github.com/google/uuid"
"github.com/gramanas/blogspace/internal/store"
@@ -25,13 +26,18 @@ func (s *Server) handleDesignForm(w http.ResponseWriter, r *http.Request) {
s.serverError(w, err)
return
}
- s.render(w, r, "dashboard/design.html", map[string]any{"theme": ParseTheme(blog.ThemeJSON), "images": images, "presets": Presets()})
+ s.render(w, r, "dashboard/design.html", designData(ParseTheme(blog.ThemeJSON), images))
+}
+
+// designData is what design.html shows; "today" is the sample for the date formats.
+func designData(theme Theme, images []store.Image) map[string]any {
+ return map[string]any{"theme": theme, "images": images, "presets": Presets(), "today": time.Now()}
}
func (s *Server) handleDesign(w http.ResponseWriter, r *http.Request) {
blog := currentBlog(r)
if err := r.ParseMultipartForm(1 << 20); err != nil && !errors.Is(err, http.ErrNotMultipart) {
- s.plainError(w, http.StatusBadRequest, "Upload too large or malformed form.")
+ s.plainError(w, http.StatusBadRequest, s.tr(r, "Upload too large or malformed form."))
return
}
theme := ThemeFromForm(ParseTheme(blog.ThemeJSON), r.Form)
@@ -40,7 +46,9 @@ func (s *Server) handleDesign(w http.ResponseWriter, r *http.Request) {
img, err := s.readUpload(r, field)
if err != nil {
images, _ := blogStore(r).ListImages(r.Context())
- s.renderStatus(w, r, http.StatusBadRequest, "dashboard/design.html", map[string]any{"theme": theme, "images": images, "presets": Presets(), "error": err.Error()})
+ d := designData(theme, images)
+ d["error"] = err.Error()
+ s.renderStatus(w, r, http.StatusBadRequest, "dashboard/design.html", d)
return
}
if img != nil {
@@ -51,7 +59,7 @@ func (s *Server) handleDesign(w http.ResponseWriter, r *http.Request) {
s.serverError(w, err)
return
}
- redirectOK(w, r, "/b/"+blog.Subdomain+"/design", "Design saved. Refresh your blog to see it.")
+ redirectOK(w, r, "/b/"+blog.Subdomain+"/design", s.tr(r, "Design saved. Refresh your blog to see it."))
}
// handleDesignPreset applies a colour scheme straight away; it is a separate
@@ -60,7 +68,7 @@ func (s *Server) handleDesignPreset(w http.ResponseWriter, r *http.Request) {
blog := currentBlog(r)
p, ok := PresetByKey(r.FormValue("preset"))
if !ok {
- s.plainError(w, http.StatusBadRequest, "Unknown colour scheme.")
+ s.plainError(w, http.StatusBadRequest, s.tr(r, "Unknown colour scheme."))
return
}
theme := ParseTheme(blog.ThemeJSON).WithPreset(p)
@@ -68,7 +76,7 @@ func (s *Server) handleDesignPreset(w http.ResponseWriter, r *http.Request) {
s.serverError(w, err)
return
}
- redirectOK(w, r, "/b/"+blog.Subdomain+"/design", "Applied the "+p.Name+" scheme. Refresh your blog to see it.")
+ redirectOK(w, r, "/b/"+blog.Subdomain+"/design", s.trf(r, "Applied the %s scheme. Refresh your blog to see it.", s.tr(r, p.Name)))
}
// handleDesignReset restores the defaults, layout modules included; images
@@ -83,7 +91,7 @@ func (s *Server) handleDesignReset(w http.ResponseWriter, r *http.Request) {
s.serverError(w, err)
return
}
- redirectOK(w, r, "/b/"+blog.Subdomain+"/design", "Design and layout reset to the defaults.")
+ redirectOK(w, r, "/b/"+blog.Subdomain+"/design", s.tr(r, "Design and layout reset to the defaults."))
}
// readUpload stores the file from a multipart field, returning nil if the field is empty.
@@ -99,8 +107,9 @@ func (s *Server) readUpload(r *http.Request, field string) (*store.Image, error)
}
func (s *Server) storeUpload(r *http.Request, fh *multipart.FileHeader) (*store.Image, error) {
+ tooBig := errors.New(s.trf(r, "Image is too large (max %s).", kbString(s.cfg.MaxUploadBytes)))
if fh.Size > s.cfg.MaxUploadBytes {
- return nil, errors.New("image is too large (max " + kbString(s.cfg.MaxUploadBytes) + ")")
+ return nil, tooBig
}
f, err := fh.Open()
if err != nil {
@@ -112,11 +121,11 @@ func (s *Server) storeUpload(r *http.Request, fh *multipart.FileHeader) (*store.
return nil, err
}
if int64(buf.Len()) > s.cfg.MaxUploadBytes {
- return nil, errors.New("image is too large (max " + kbString(s.cfg.MaxUploadBytes) + ")")
+ return nil, tooBig
}
ct := http.DetectContentType(buf.Bytes())
if !allowedImageTypes[ct] {
- return nil, errors.New("only PNG, JPEG, GIF, WebP and ICO images are accepted")
+ return nil, errors.New(s.tr(r, "Only PNG, JPEG, GIF, WebP and ICO images are accepted."))
}
name := filepath.Base(fh.Filename)
if name == "" || name == "." || len(name) > 120 {
@@ -174,7 +183,7 @@ func (s *Server) handleImageUpload(w http.ResponseWriter, r *http.Request) {
s.plainError(w, http.StatusBadRequest, msg)
}
if err := r.ParseMultipartForm(1 << 20); err != nil {
- fail("Upload too large or malformed form.")
+ fail(s.tr(r, "Upload too large or malformed form."))
return
}
img, err := s.readUpload(r, "file")
@@ -183,14 +192,14 @@ func (s *Server) handleImageUpload(w http.ResponseWriter, r *http.Request) {
return
}
if img == nil {
- fail("Choose a file first.")
+ fail(s.tr(r, "Choose a file first."))
return
}
if wantJSON {
writeJSON(w, http.StatusOK, map[string]string{"id": img.ID.String(), "filename": img.Filename, "markdown": imageMarkdown(img)})
return
}
- redirectOK(w, r, "/b/"+blog.Subdomain+"/images", "Uploaded "+img.Filename+".")
+ redirectOK(w, r, "/b/"+blog.Subdomain+"/images", s.trf(r, "Uploaded %s.", img.Filename))
}
func writeJSON(w http.ResponseWriter, status int, v any) {
@@ -232,5 +241,5 @@ func (s *Server) handleImageDelete(w http.ResponseWriter, r *http.Request) {
return
}
}
- redirectOK(w, r, "/b/"+blog.Subdomain+"/images", "Image deleted.")
+ redirectOK(w, r, "/b/"+blog.Subdomain+"/images", s.tr(r, "Image deleted."))
}