package postctl import ( "errors" "html/template" "net/http" "strconv" "time" "github.com/kirsle/blog/internal/markdown" "github.com/kirsle/blog/internal/middleware/auth" "github.com/kirsle/blog/internal/render" "github.com/kirsle/blog/internal/responses" "github.com/kirsle/blog/internal/types" "github.com/kirsle/blog/models/posts" ) // editHandler is the blog writing and editing page. func editHandler(w http.ResponseWriter, r *http.Request) { v := map[string]interface{}{ "preview": "", } var post *posts.Post var isNew bool // Are we editing an existing post? if idStr := r.FormValue("id"); idStr != "" { id, err := strconv.Atoi(idStr) if err == nil { post, err = posts.Load(id) if err != nil { v["Error"] = errors.New("that post ID was not found") post = posts.New() isNew = true } } } else { post = posts.New() isNew = true } if r.Method == http.MethodPost { // Parse from form values. post.ParseForm(r) // Previewing, or submitting? switch r.FormValue("submit") { case "preview": if post.ContentType == string(types.MARKDOWN) { v["preview"] = template.HTML(markdown.RenderTrustedMarkdown(post.Body)) } else { v["preview"] = template.HTML(post.Body) } case "post": if err := post.Validate(); err != nil { v["Error"] = err } else { author, _ := auth.CurrentUser(r) post.AuthorID = author.ID // When editing, allow to not touch the last updated time. if !isNew && r.FormValue("no-update") == "true" { post.Updated = post.Created } else { post.Updated = time.Now().UTC() } err = post.Save() if err != nil { v["Error"] = err } else { responses.Flash(w, r, "Post created!") responses.Redirect(w, "/"+post.Fragment) } } } } v["post"] = post render.Template(w, r, "blog/edit", v) } // deleteHandler to delete a blog entry. func deleteHandler(w http.ResponseWriter, r *http.Request) { var post *posts.Post v := map[string]interface{}{ "Post": nil, } var idStr string if r.Method == http.MethodPost { idStr = r.FormValue("id") } else { idStr = r.URL.Query().Get("id") } if idStr == "" { responses.FlashAndRedirect(w, r, "/admin", "No post ID given for deletion!") return } // Convert the post ID to an int. id, err := strconv.Atoi(idStr) if err == nil { post, err = posts.Load(id) if err != nil { responses.FlashAndRedirect(w, r, "/admin", "That post ID was not found.") return } } if r.Method == http.MethodPost { post.Delete() responses.FlashAndRedirect(w, r, "/admin", "Blog entry deleted!") return } v["Post"] = post render.Template(w, r, "blog/delete", v) }