diff options
Diffstat (limited to 'internal/admin/server.go')
| -rw-r--r-- | internal/admin/server.go | 137 |
1 files changed, 73 insertions, 64 deletions
diff --git a/internal/admin/server.go b/internal/admin/server.go index 410560f..33413ee 100644 --- a/internal/admin/server.go +++ b/internal/admin/server.go @@ -122,37 +122,37 @@ func (s *Server) authMiddleware() gin.HandlerFunc { // ── Handlers ───────────────────────────────────────────────────────────────── -func (s *Server) handleList(w http.ResponseWriter, r *http.Request) { +func (s *Server) handleList(c *gin.Context) { posts, err := s.listPosts() if err != nil { - http.Error(w, "Failed to list posts: "+err.Error(), http.StatusInternalServerError) + c.HTML(http.StatusInternalServerError, "base", gin.H{ + "Title": "Error", + "ContentTemplate": "error-content", + "Message": "Failed to list posts: " + err.Error(), + }) return } - s.render(w, "base", map[string]any{ - "Title": "Posts", - "ContentTemplate": "list-content", - "Posts": posts, + c.HTML(http.StatusOK, "base", gin.H{ + "Title": "Posts", + "ContentTemplate": "list-content", + "Posts": posts, }) } -func (s *Server) handleNew(w http.ResponseWriter, r *http.Request) { - if r.Method == http.MethodPost { - s.handleNewPost(w, r) - return - } - s.render(w, "base", map[string]any{ - "Title": "New Post", - "ContentTemplate": "form-content", - "Action": "/admin/new", - "Post": Post{Date: time.Now().Format("2006-01-02")}, - "IsNew": true, +func (s *Server) handleNew(c *gin.Context) { + c.HTML(http.StatusOK, "base", gin.H{ + "Title": "New Post", + "ContentTemplate": "form-content", + "Action": "/admin/new", + "Post": Post{Date: time.Now().Format("2006-01-02")}, + "IsNew": true, }) } -func (s *Server) handleNewPost(w http.ResponseWriter, r *http.Request) { - p := postFromForm(r) +func (s *Server) handleNewPost(c *gin.Context) { + p := postFromForm(c) if p.Title == "" { - s.renderError(w, "Title is required") + s.renderError(c, "Title is required") return } if p.Slug == "" { @@ -161,67 +161,86 @@ func (s *Server) handleNewPost(w http.ResponseWriter, r *http.Request) { mdPath := filepath.Join(s.PostsDir, p.Slug+".md") if err := os.MkdirAll(s.PostsDir, 0755); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) + c.HTML(http.StatusInternalServerError, "base", gin.H{ + "Title": "Error", + "ContentTemplate": "error-content", + "Message": err.Error(), + }) return } if _, err := os.Stat(mdPath); err == nil { - s.renderError(w, fmt.Sprintf("Post %q already exists", p.Slug)) + s.renderError(c, fmt.Sprintf("Post %q already exists", p.Slug)) return } if err := writePostFile(mdPath, p); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) + c.HTML(http.StatusInternalServerError, "base", gin.H{ + "Title": "Error", + "ContentTemplate": "error-content", + "Message": err.Error(), + }) return } s.rebuild(mdPath) - http.Redirect(w, r, "/admin/", http.StatusSeeOther) + c.Redirect(http.StatusSeeOther, "/admin/") } -func (s *Server) handleEdit(w http.ResponseWriter, r *http.Request, slug string) { +func (s *Server) handleEdit(c *gin.Context) { + slug := c.Param("slug") mdPath := filepath.Join(s.PostsDir, slug+".md") p, err := readPostFile(mdPath, slug) if err != nil { - http.NotFound(w, r) + c.HTML(http.StatusNotFound, "base", gin.H{ + "Title": "Not Found", + "ContentTemplate": "error-content", + "Message": "Post not found", + }) return } - if r.Method == http.MethodPost { - updated := postFromForm(r) + + if c.Request.Method == http.MethodPost { + updated := postFromForm(c) updated.Slug = slug // slug is immutable after creation if updated.Title == "" { - s.renderError(w, "Title is required") + s.renderError(c, "Title is required") return } if err := writePostFile(mdPath, updated); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) + c.HTML(http.StatusInternalServerError, "base", gin.H{ + "Title": "Error", + "ContentTemplate": "error-content", + "Message": err.Error(), + }) return } s.rebuild(mdPath) - http.Redirect(w, r, "/admin/", http.StatusSeeOther) + c.Redirect(http.StatusSeeOther, "/admin/") return } - s.render(w, "base", map[string]any{ - "Title": "Edit Post", - "ContentTemplate": "form-content", - "Action": "/admin/" + slug + "/edit", - "Post": p, - "IsNew": false, + c.HTML(http.StatusOK, "base", gin.H{ + "Title": "Edit Post", + "ContentTemplate": "form-content", + "Action": "/admin/" + slug, + "Post": p, + "IsNew": false, }) } -func (s *Server) handleDelete(w http.ResponseWriter, r *http.Request, slug string) { - if r.Method != http.MethodPost { - http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) - return - } +func (s *Server) handleDelete(c *gin.Context) { + slug := c.Param("slug") mdPath := filepath.Join(s.PostsDir, slug+".md") if err := os.Remove(mdPath); err != nil && !os.IsNotExist(err) { - http.Error(w, err.Error(), http.StatusInternalServerError) + c.HTML(http.StatusInternalServerError, "base", gin.H{ + "Title": "Error", + "ContentTemplate": "error-content", + "Message": err.Error(), + }) return } if s.Builder != nil { _ = s.Builder.RemovePage(mdPath) } - http.Redirect(w, r, "/admin/", http.StatusSeeOther) + c.Redirect(http.StatusSeeOther, "/admin/") } func (s *Server) rebuild(mdPath string) { @@ -254,31 +273,21 @@ func (s *Server) listPosts() ([]Post, error) { return posts, nil } -func (s *Server) render(w http.ResponseWriter, name string, data map[string]any) { - w.Header().Set("Content-Type", "text/html; charset=utf-8") - if err := s.tmpl.ExecuteTemplate(w, name, data); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } -} - -func (s *Server) renderError(w http.ResponseWriter, msg string) { - w.Header().Set("Content-Type", "text/html; charset=utf-8") - w.WriteHeader(http.StatusBadRequest) - _ = s.tmpl.ExecuteTemplate(w, "base", map[string]any{ - "Title": "Error", - "ContentTemplate": "error-content", - "Message": msg, +func (s *Server) renderError(c *gin.Context, msg string) { + c.HTML(http.StatusBadRequest, "base", gin.H{ + "Title": "Error", + "ContentTemplate": "error-content", + "Message": msg, }) } // postFromForm reads a post from an HTTP form submission. -func postFromForm(r *http.Request) Post { - _ = r.ParseForm() +func postFromForm(c *gin.Context) Post { return Post{ - Title: strings.TrimSpace(r.FormValue("title")), - Date: strings.TrimSpace(r.FormValue("date")), - Tags: strings.TrimSpace(r.FormValue("tags")), - Content: r.FormValue("content"), + Title: strings.TrimSpace(c.PostForm("title")), + Date: strings.TrimSpace(c.PostForm("date")), + Tags: strings.TrimSpace(c.PostForm("tags")), + Content: c.PostForm("content"), } } |
