Implement saving of new and edited posts
This commit is contained in:
parent
75044eef03
commit
2c4b617dde
@ -216,6 +216,9 @@ func (a *api) handler() http.Handler {
|
|||||||
apiutil.MethodMux(map[string]http.Handler{
|
apiutil.MethodMux(map[string]http.Handler{
|
||||||
"GET": a.renderPostHandler(),
|
"GET": a.renderPostHandler(),
|
||||||
"EDIT": a.editPostHandler(),
|
"EDIT": a.editPostHandler(),
|
||||||
|
"POST": authMiddleware(auther,
|
||||||
|
formMiddleware(a.postPostHandler()),
|
||||||
|
),
|
||||||
"DELETE": authMiddleware(auther,
|
"DELETE": authMiddleware(auther,
|
||||||
formMiddleware(a.deletePostHandler()),
|
formMiddleware(a.deletePostHandler()),
|
||||||
),
|
),
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gomarkdown/markdown"
|
"github.com/gomarkdown/markdown"
|
||||||
"github.com/gomarkdown/markdown/html"
|
"github.com/gomarkdown/markdown/html"
|
||||||
@ -168,6 +169,35 @@ func (a *api) editPostHandler() http.Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *api) postPostHandler() http.Handler {
|
||||||
|
|
||||||
|
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
p := post.Post{
|
||||||
|
ID: r.PostFormValue("id"),
|
||||||
|
Title: r.PostFormValue("title"),
|
||||||
|
Description: r.PostFormValue("description"),
|
||||||
|
Tags: strings.Fields(r.PostFormValue("tags")),
|
||||||
|
Series: r.PostFormValue("series"),
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Body = strings.TrimSpace(r.PostFormValue("body"))
|
||||||
|
// textareas encode newlines as CRLF for historical reasons
|
||||||
|
p.Body = strings.ReplaceAll(p.Body, "\r\n", "\n")
|
||||||
|
|
||||||
|
if err := a.params.PostStore.Set(p, time.Now()); err != nil {
|
||||||
|
apiutil.InternalServerError(
|
||||||
|
rw, r, fmt.Errorf("storing post with id %q: %w", p.ID, err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
redirectPath := fmt.Sprintf("posts/%s?method=edit", p.ID)
|
||||||
|
|
||||||
|
a.executeRedirectTpl(rw, r, redirectPath)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (a *api) deletePostHandler() http.Handler {
|
func (a *api) deletePostHandler() http.Handler {
|
||||||
|
|
||||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -1,17 +1,31 @@
|
|||||||
{{ define "body" }}
|
{{ define "body" }}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href="{{ BlogURL "posts/" }}">
|
||||||
|
<button>Back to Posts</button>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<form method="POST" action="{{ BlogURL "posts/" }}">
|
<form method="POST" action="{{ BlogURL "posts/" }}">
|
||||||
|
|
||||||
|
{{ .CSRFFormInput }}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
<div class="columns six">
|
<div class="columns six">
|
||||||
<label for="idInput">Unique ID (e.g. "how-to-fly-a-kite")</label>
|
<label for="idInput">Unique ID</label>
|
||||||
|
{{ if eq .Payload.ID "" }}
|
||||||
<input
|
<input
|
||||||
id="idInput"
|
id="idInput"
|
||||||
name="id"
|
name="id"
|
||||||
class="u-full-width"
|
class="u-full-width"
|
||||||
type="text"
|
type="text"
|
||||||
|
placeholder="e.g. how-to-fly-a-kite"
|
||||||
value="{{ .Payload.ID }}" />
|
value="{{ .Payload.ID }}" />
|
||||||
|
{{ else }}
|
||||||
|
<a href="{{ PostURL .Payload.ID }}" target="_blank">{{ .Payload.ID }}</a>
|
||||||
|
<input name="id" type="hidden" value="{{ .Payload.ID }}" />
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="columns three">
|
<div class="columns three">
|
||||||
@ -68,7 +82,7 @@
|
|||||||
placeholder="Blog body"
|
placeholder="Blog body"
|
||||||
style="height: 50vh;"
|
style="height: 50vh;"
|
||||||
>
|
>
|
||||||
{{ .Payload.Body }}
|
{{- .Payload.Body -}}
|
||||||
</textarea>
|
</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -124,6 +124,11 @@ func (s *store) withTx(cb func(*sql.Tx) error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) Set(post Post, now time.Time) error {
|
func (s *store) Set(post Post, now time.Time) error {
|
||||||
|
|
||||||
|
if post.ID == "" {
|
||||||
|
return errors.New("post ID can't be empty")
|
||||||
|
}
|
||||||
|
|
||||||
return s.withTx(func(tx *sql.Tx) error {
|
return s.withTx(func(tx *sql.Tx) error {
|
||||||
|
|
||||||
nowTS := now.Unix()
|
nowTS := now.Unix()
|
||||||
|
Loading…
Reference in New Issue
Block a user