|
|
|
@ -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) |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|