aboutsummaryrefslogtreecommitdiffstats
path: root/internal/web/handlers_posts.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/web/handlers_posts.go')
-rw-r--r--internal/web/handlers_posts.go25
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 {