refactor: simplify toggle handlers to return 204 No Content

Remove empty toggle templates (length-toggle.html, theme-toggle.html,
logo-toggle.html) that were just placeholders. The frontend uses
hx-swap="none" so the response body was always ignored anyway.

Now the handlers:
- Set the preference cookie
- Return 204 No Content immediately
- Hyperscript handles the UI state toggle on the frontend

This removes unnecessary template rendering overhead and cleans up
dead code. Tests updated to expect 204 instead of 200.
This commit is contained in:
juanatsap
2025-12-01 14:16:24 +00:00
parent a97d6bc3fd
commit e0d445b92a
5 changed files with 18 additions and 86 deletions
+9 -77
View File
@@ -32,35 +32,9 @@ func (h *CVHandler) ToggleLength(w http.ResponseWriter, r *http.Request) {
// Save new state // Save new state
middleware.SetPreferenceCookie(w, "cv-length", newLength) middleware.SetPreferenceCookie(w, "cv-length", newLength)
// Get language from query or use current preference // Return 204 No Content - frontend uses hx-swap="none" so response body is ignored
lang := r.URL.Query().Get("lang") // The cookie is set and hyperscript handles the UI state toggle
if lang == "" { w.WriteHeader(http.StatusNoContent)
lang = prefs.CVLanguage
}
// Prepare template data with length state
cvLengthClass := "cv-short"
if newLength == "long" {
cvLengthClass = "cv-long"
}
data := map[string]interface{}{
"Lang": lang,
"CVLengthClass": cvLengthClass,
}
// Render length-toggle template with out-of-band swaps
tmpl, err := h.templates.Render("length-toggle.html")
if err != nil {
HandleError(w, r, TemplateError(err, "length-toggle.html"))
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
if err := tmpl.Execute(w, data); err != nil {
HandleError(w, r, TemplateError(err, "length-toggle.html"))
return
}
} }
// ToggleIcons handles icon visibility toggle using atomic out-of-band swaps // ToggleIcons handles icon visibility toggle using atomic out-of-band swaps
@@ -83,30 +57,9 @@ func (h *CVHandler) ToggleIcons(w http.ResponseWriter, r *http.Request) {
// Save new state // Save new state
middleware.SetPreferenceCookie(w, "cv-icons", newIcons) middleware.SetPreferenceCookie(w, "cv-icons", newIcons)
// Get language from query or use current preference // Return 204 No Content - frontend uses hx-swap="none" so response body is ignored
lang := r.URL.Query().Get("lang") // The cookie is set and hyperscript handles the UI state toggle
if lang == "" { w.WriteHeader(http.StatusNoContent)
lang = prefs.CVLanguage
}
// Prepare template data with logo state
data := map[string]interface{}{
"Lang": lang,
"ShowIcons": (newIcons == "show"),
}
// Render logo-toggle template with out-of-band swaps
tmpl, err := h.templates.Render("logo-toggle.html")
if err != nil {
HandleError(w, r, TemplateError(err, "logo-toggle.html"))
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
if err := tmpl.Execute(w, data); err != nil {
HandleError(w, r, TemplateError(err, "logo-toggle.html"))
return
}
} }
// SwitchLanguage handles language switching with atomic updates // SwitchLanguage handles language switching with atomic updates
@@ -181,28 +134,7 @@ func (h *CVHandler) ToggleTheme(w http.ResponseWriter, r *http.Request) {
// Save new state // Save new state
middleware.SetPreferenceCookie(w, "cv-theme", newTheme) middleware.SetPreferenceCookie(w, "cv-theme", newTheme)
// Get language from query or use current preference // Return 204 No Content - frontend uses hx-swap="none" so response body is ignored
lang := r.URL.Query().Get("lang") // The cookie is set and hyperscript handles the UI state toggle
if lang == "" { w.WriteHeader(http.StatusNoContent)
lang = prefs.CVLanguage
}
// Prepare template data with theme state
data := map[string]interface{}{
"Lang": lang,
"ThemeClean": (newTheme == "clean"),
}
// Render theme-toggle template with out-of-band swaps
tmpl, err := h.templates.Render("theme-toggle.html")
if err != nil {
HandleError(w, r, TemplateError(err, "theme-toggle.html"))
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
if err := tmpl.Execute(w, data); err != nil {
HandleError(w, r, TemplateError(err, "theme-toggle.html"))
return
}
} }
+9 -6
View File
@@ -60,8 +60,9 @@ func TestToggleLength(t *testing.T) {
w := httptest.NewRecorder() w := httptest.NewRecorder()
handler.ToggleLength(w, req) handler.ToggleLength(w, req)
if w.Code != http.StatusOK { // 204 No Content - frontend uses hx-swap="none" so response body is ignored
t.Errorf("Expected status OK, got %d", w.Code) if w.Code != http.StatusNoContent {
t.Errorf("Expected status No Content (204), got %d", w.Code)
} }
// Check that response sets the toggled cookie // Check that response sets the toggled cookie
@@ -131,8 +132,9 @@ func TestToggleIcons(t *testing.T) {
w := httptest.NewRecorder() w := httptest.NewRecorder()
handler.ToggleIcons(w, req) handler.ToggleIcons(w, req)
if w.Code != http.StatusOK { // 204 No Content - frontend uses hx-swap="none" so response body is ignored
t.Errorf("Expected status OK, got %d", w.Code) if w.Code != http.StatusNoContent {
t.Errorf("Expected status No Content (204), got %d", w.Code)
} }
}) })
} }
@@ -253,8 +255,9 @@ func TestToggleTheme(t *testing.T) {
w := httptest.NewRecorder() w := httptest.NewRecorder()
handler.ToggleTheme(w, req) handler.ToggleTheme(w, req)
if w.Code != http.StatusOK { // 204 No Content - frontend uses hx-swap="none" so response body is ignored
t.Errorf("Expected status OK, got %d", w.Code) if w.Code != http.StatusNoContent {
t.Errorf("Expected status No Content (204), got %d", w.Code)
} }
// Verify theme cookie was set // Verify theme cookie was set
-1
View File
@@ -1 +0,0 @@
<!-- Template not used - toggles use hx-swap="none" with inline hyperscript -->
-1
View File
@@ -1 +0,0 @@
<!-- Template not used - toggles use hx-swap="none" with inline hyperscript -->
-1
View File
@@ -1 +0,0 @@
<!-- Template not used - toggles use hx-swap="none" with inline hyperscript -->