Add preview button to edit post page

main
Brian Picciano 2 years ago
parent 2c4b617dde
commit f69ed83de7
  1. 1
      srv/src/api/api.go
  2. 121
      srv/src/api/posts.go
  3. 19
      srv/src/api/tpl/edit-post.html

@ -222,6 +222,7 @@ func (a *api) handler() http.Handler {
"DELETE": authMiddleware(auther,
formMiddleware(a.deletePostHandler()),
),
"PREVIEW": formMiddleware(a.previewPostHandler()),
}),
))
v2Mux.Handle("/assets/", http.StripPrefix("/assets",

@ -16,32 +16,13 @@ import (
"github.com/mediocregopher/blog.mediocregopher.com/srv/post"
)
func (a *api) renderPostHandler() http.Handler {
tpl := a.mustParseBasedTpl("post.html")
renderIndexHandler := a.renderPostsIndexHandler()
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
id := strings.TrimSuffix(filepath.Base(r.URL.Path), ".html")
if id == "/" {
renderIndexHandler.ServeHTTP(rw, r)
return
}
storedPost, err := a.params.PostStore.GetByID(id)
if errors.Is(err, post.ErrPostNotFound) {
http.Error(rw, "Post not found", 404)
return
} else if err != nil {
apiutil.InternalServerError(
rw, r, fmt.Errorf("fetching post with id %q: %w", id, err),
)
return
}
type postTplPayload struct {
post.StoredPost
SeriesPrevious, SeriesNext *post.StoredPost
Body template.HTML
}
func (a *api) postToPostTplPayload(storedPost post.StoredPost) (postTplPayload, error) {
parserExt := parser.CommonExtensions | parser.AutoHeadingIDs
parser := parser.NewWithExtensions(parserExt)
@ -50,11 +31,7 @@ func (a *api) renderPostHandler() http.Handler {
renderedBody := markdown.ToHTML([]byte(storedPost.Body), parser, htmlRenderer)
tplPayload := struct {
post.StoredPost
SeriesPrevious, SeriesNext *post.StoredPost
Body template.HTML
}{
tplPayload := postTplPayload{
StoredPost: storedPost,
Body: template.HTML(renderedBody),
}
@ -63,11 +40,9 @@ func (a *api) renderPostHandler() http.Handler {
seriesPosts, err := a.params.PostStore.GetBySeries(series)
if err != nil {
apiutil.InternalServerError(
rw, r,
fmt.Errorf("fetching posts for series %q: %w", series, err),
return postTplPayload{}, fmt.Errorf(
"fetching posts for series %q: %w", series, err,
)
return
}
var foundThis bool
@ -91,6 +66,47 @@ func (a *api) renderPostHandler() http.Handler {
}
}
return tplPayload, nil
}
func (a *api) renderPostHandler() http.Handler {
tpl := a.mustParseBasedTpl("post.html")
renderIndexHandler := a.renderPostsIndexHandler()
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
id := strings.TrimSuffix(filepath.Base(r.URL.Path), ".html")
if id == "/" {
renderIndexHandler.ServeHTTP(rw, r)
return
}
storedPost, err := a.params.PostStore.GetByID(id)
if errors.Is(err, post.ErrPostNotFound) {
http.Error(rw, "Post not found", 404)
return
} else if err != nil {
apiutil.InternalServerError(
rw, r, fmt.Errorf("fetching post with id %q: %w", id, err),
)
return
}
tplPayload, err := a.postToPostTplPayload(storedPost)
if err != nil {
apiutil.InternalServerError(
rw, r, fmt.Errorf(
"generating template payload for post with id %q: %w",
id, err,
),
)
return
}
executeTemplate(rw, r, tpl, tplPayload)
})
}
@ -169,9 +185,7 @@ func (a *api) editPostHandler() http.Handler {
})
}
func (a *api) postPostHandler() http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
func postFromPostReq(r *http.Request) post.Post {
p := post.Post{
ID: r.PostFormValue("id"),
@ -185,6 +199,15 @@ func (a *api) postPostHandler() http.Handler {
// textareas encode newlines as CRLF for historical reasons
p.Body = strings.ReplaceAll(p.Body, "\r\n", "\n")
return p
}
func (a *api) postPostHandler() http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
p := postFromPostReq(r)
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),
@ -225,3 +248,27 @@ func (a *api) deletePostHandler() http.Handler {
})
}
func (a *api) previewPostHandler() http.Handler {
tpl := a.mustParseBasedTpl("post.html")
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
storedPost := post.StoredPost{
Post: postFromPostReq(r),
PublishedAt: time.Now(),
}
tplPayload, err := a.postToPostTplPayload(storedPost)
if err != nil {
apiutil.InternalServerError(
rw, r, fmt.Errorf("generating template payload: %w", err),
)
return
}
executeTemplate(rw, r, tpl, tplPayload)
})
}

@ -1,11 +1,5 @@
{{ define "body" }}
<p>
<a href="{{ BlogURL "posts/" }}">
<button>Back to Posts</button>
</a>
</p>
<form method="POST" action="{{ BlogURL "posts/" }}">
{{ .CSRFFormInput }}
@ -87,7 +81,18 @@
</div>
</div>
<input type="submit" value="Save" />
<input
type="submit"
value="Preview"
formaction="{{ BlogURL "posts/" }}{{ .Payload.ID }}?method=preview"
formtarget="_blank"
/>
<input type="submit" value="Save" formaction="{{ BlogURL "posts/" }}" />
<a href="{{ BlogURL "posts/" }}">
<button type="button">Cancel</button>
</a>
</form>

Loading…
Cancel
Save