diff options
Diffstat (limited to 'internal/web/handlers_posts.go')
| -rw-r--r-- | internal/web/handlers_posts.go | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/internal/web/handlers_posts.go b/internal/web/handlers_posts.go index 88d5c20..8327912 100644 --- a/internal/web/handlers_posts.go +++ b/internal/web/handlers_posts.go @@ -5,6 +5,7 @@ import ( "net/http" "strconv" "strings" + "time" "github.com/gramanas/blogspace/internal/markdown" "github.com/gramanas/blogspace/internal/slug" @@ -46,7 +47,7 @@ func (s *Server) handlePostForm(w http.ResponseWriter, r *http.Request) { s.serverError(w, err) return } - p := &store.Post{Published: true} + p := &store.Post{Published: true, CreatedAt: time.Now()} if r.PathValue("id") != "" { if p = s.loadPost(w, r); p == nil { return @@ -66,7 +67,7 @@ func (s *Server) handlePostSave(w http.ResponseWriter, r *http.Request) { s.serverError(w, err) return } - p := &store.Post{} + p := &store.Post{CreatedAt: time.Now()} if r.PathValue("id") != "" { if p = s.loadPost(w, r); p == nil { return @@ -84,6 +85,13 @@ func (s *Server) handlePostSave(w http.ResponseWriter, r *http.Request) { fail := func(status int, msg string) { s.renderStatus(w, r, status, "dashboard/post_form.html", map[string]any{"post": p, "pages": pages, "error": msg}) } + if at := strings.TrimSpace(r.FormValue("posted_at")); at != "" { // blank keeps the current date + var ok bool + if p.CreatedAt, ok = parsePostDate(at); !ok { + fail(http.StatusBadRequest, s.tr(r, "Enter the date as YYYY-MM-DD HH:MM.")) + return + } + } img, err := s.readUpload(r, "inline_image") if err != nil { fail(http.StatusBadRequest, s.tr(r, "Image not added:")+" "+err.Error()) @@ -137,6 +145,19 @@ func (s *Server) handlePostSave(w http.ResponseWriter, r *http.Request) { redirectOK(w, r, "/b/"+blog.Subdomain+"/posts/"+strconv.FormatInt(p.ID, 10)+"/edit", s.tr(r, "Saved. Refresh your blog to see it.")) } +// parsePostDate reads the post form's date: what a datetime-local input sends, +// or the same typed by hand where the browser shows a plain text box. The time +// of day is optional. Times are taken in the server's zone, which is also the +// zone the blog displays them in. +func parsePostDate(v string) (time.Time, bool) { + for _, layout := range []string{"2006-01-02T15:04", "2006-01-02 15:04", "2006-01-02T15:04:05", "2006-01-02"} { + if t, err := time.ParseInLocation(layout, v, time.Local); err == nil { + return t, true + } + } + return time.Time{}, false +} + func (s *Server) handlePostDeleteConfirm(w http.ResponseWriter, r *http.Request) { p := s.loadPost(w, r) if p == nil { |
