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.go60
1 files changed, 35 insertions, 25 deletions
diff --git a/internal/web/handlers_design.go b/internal/web/handlers_design.go
index 5853436..acc7569 100644
--- a/internal/web/handlers_design.go
+++ b/internal/web/handlers_design.go
@@ -141,39 +141,49 @@ func (s *Server) handleDesign(w http.ResponseWriter, r *http.Request) {
if p, ok := PresetByKey(r.FormValue("preset")); ok {
v.Theme = v.Theme.WithPreset(p)
}
- // The form is shown again with everything that was sent, plus the message.
- fail := func(msg string) {
- d, err := s.designData(r, v)
- if err != nil {
- s.serverError(w, err)
- return
- }
- d["error"] = msg
- s.renderStatus(w, r, http.StatusBadRequest, "dashboard/design.html", d)
- }
- // Optional direct uploads from the pickers.
- for field, dst := range map[string]*string{"bg_image_file": &v.Theme.BgImage, "header_image_file": &v.Theme.HeaderImage, "logo_file": &v.Theme.Logo, "favicon_file": &v.Theme.Favicon} {
- img, err := s.readUpload(r, field, true)
- if err != nil {
- fail(err.Error())
- return
- }
- if img != nil {
- *dst = img.ID.String()
+ // Every part of the form is read before any problem is reported, so the
+ // form shown again carries all of it: a module or menu row that was left
+ // out here would be deleted by the next save. The first problem is the
+ // one reported.
+ var problem error
+ note := func(err error) {
+ if problem == nil {
+ problem = err
}
}
var err error
- if v.Modules, err = parseModules(r.Form, lang, blog.Language); err != nil {
- fail(err.Error())
- return
- }
+ v.Modules, err = parseModules(r.Form, lang, blog.Language)
+ note(err)
pages, err := blogStore(r).ListPages(r.Context())
if err != nil {
s.serverError(w, err)
return
}
- if v.Menu, err = parseMenu(r.Form, lang, pages); err != nil {
- fail(err.Error())
+ v.Menu, err = parseMenu(r.Form, lang, pages)
+ note(err)
+ // Optional direct uploads from the pickers. One that is stored stays
+ // chosen in the form even when something else is rejected.
+ for _, u := range []struct {
+ field string
+ dst *string
+ }{{"bg_image_file", &v.Theme.BgImage}, {"header_image_file", &v.Theme.HeaderImage}, {"logo_file", &v.Theme.Logo}, {"favicon_file", &v.Theme.Favicon}} {
+ img, err := s.readUpload(r, u.field, true)
+ if err != nil {
+ note(err)
+ continue
+ }
+ if img != nil {
+ *u.dst = img.ID.String()
+ }
+ }
+ if problem != nil {
+ d, err := s.designData(r, v)
+ if err != nil {
+ s.serverError(w, err)
+ return
+ }
+ d["error"] = problem.Error()
+ s.renderStatus(w, r, http.StatusBadRequest, "dashboard/design.html", d)
return
}
if err := blogStore(r).SaveDesign(r.Context(), v.Theme.JSON(), v.Modules, v.Menu); err != nil {