mirror of https://github.com/jlelse/GoBlog
Add editor to create, update or delete posts
This commit is contained in:
parent
366514699d
commit
eeb68dbba9
|
@ -0,0 +1,85 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const editorPath = "/editor"
|
||||
|
||||
func serveEditor(w http.ResponseWriter, r *http.Request) {
|
||||
render(w, templateEditor, &renderData{})
|
||||
}
|
||||
|
||||
func serveEditorPost(w http.ResponseWriter, r *http.Request) {
|
||||
if action := r.FormValue("editoraction"); action != "" {
|
||||
if action == "loadupdate" {
|
||||
parsedURL, err := url.Parse(r.FormValue("url"))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
post, err := getPost(parsedURL.Path)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
mf := post.toMfItem()
|
||||
render(w, templateEditor, &renderData{
|
||||
Data: map[string]interface{}{
|
||||
"UpdatePostURL": parsedURL.String(),
|
||||
"UpdatePostContent": mf.Properties.Content[0],
|
||||
},
|
||||
})
|
||||
return
|
||||
} else if action == "updatepost" {
|
||||
urlValue := r.FormValue("url")
|
||||
content := r.FormValue("content")
|
||||
mf := map[string]interface{}{
|
||||
"action": actionUpdate,
|
||||
"url": urlValue,
|
||||
"replace": map[string][]string{
|
||||
"content": {
|
||||
content,
|
||||
},
|
||||
},
|
||||
}
|
||||
jsonBytes, err := json.Marshal(mf)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
req, err := http.NewRequest(http.MethodPost, "", bytes.NewReader(jsonBytes))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
req.Header.Set(contentType, contentTypeJSON)
|
||||
editorMicropubPost(w, req)
|
||||
return
|
||||
}
|
||||
http.Error(w, "unknown editoraction", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
editorMicropubPost(w, r)
|
||||
}
|
||||
|
||||
func editorMicropubPost(w http.ResponseWriter, r *http.Request) {
|
||||
recorder := httptest.NewRecorder()
|
||||
addAllScopes(http.HandlerFunc(serveMicropubPost)).ServeHTTP(recorder, r)
|
||||
result := recorder.Result()
|
||||
if location := result.Header.Get("Location"); location != "" {
|
||||
http.Redirect(w, r, result.Header.Get("Location"), http.StatusFound)
|
||||
return
|
||||
}
|
||||
if result.StatusCode >= 200 && result.StatusCode <= 400 {
|
||||
http.Redirect(w, r, editorPath, http.StatusFound)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(result.StatusCode)
|
||||
body, _ := ioutil.ReadAll(result.Body)
|
||||
w.Write(body)
|
||||
}
|
7
http.go
7
http.go
|
@ -106,6 +106,13 @@ func buildHandler() (http.Handler, error) {
|
|||
}
|
||||
})
|
||||
|
||||
// Editor
|
||||
r.Route("/editor", func(mpRouter chi.Router) {
|
||||
mpRouter.Use(authMiddleware)
|
||||
mpRouter.Get("/", serveEditor)
|
||||
mpRouter.Post("/", serveEditorPost)
|
||||
})
|
||||
|
||||
// IndieAuth
|
||||
r.Route("/indieauth", func(indieauthRouter chi.Router) {
|
||||
indieauthRouter.Use(middleware.NoCache)
|
||||
|
|
|
@ -21,3 +21,10 @@ func checkIndieAuth(next http.Handler) http.Handler {
|
|||
return
|
||||
})
|
||||
}
|
||||
|
||||
func addAllScopes(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
next.ServeHTTP(rw, r.WithContext(context.WithValue(r.Context(), "scope", "create update delete media")))
|
||||
return
|
||||
})
|
||||
}
|
||||
|
|
|
@ -90,6 +90,8 @@ func (p *post) toMfItem() *microformatItem {
|
|||
params["path"] = []string{p.Path}
|
||||
params["section"] = []string{p.Section}
|
||||
params["blog"] = []string{p.Blog}
|
||||
params["published"] = []string{p.Published}
|
||||
params["updated"] = []string{p.Updated}
|
||||
pb, _ := yaml.Marshal(p.Parameters)
|
||||
content := fmt.Sprintf("---\n%s---\n%s", string(pb), p.Content)
|
||||
return µformatItem{
|
||||
|
@ -185,8 +187,7 @@ func serveMicropubPost(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Add("Location", p.fullURL())
|
||||
w.WriteHeader(http.StatusAccepted)
|
||||
http.Redirect(w, r, p.fullURL(), http.StatusAccepted)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -424,7 +425,7 @@ func micropubDelete(w http.ResponseWriter, r *http.Request, u *url.URL) {
|
|||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
http.Redirect(w, r, u.String(), http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -557,4 +558,5 @@ func micropubUpdate(w http.ResponseWriter, r *http.Request, u *url.URL, mf *micr
|
|||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, p.fullURL(), http.StatusNoContent)
|
||||
}
|
||||
|
|
|
@ -56,6 +56,13 @@ func (p *post) checkPost() error {
|
|||
if p.Blog == "" {
|
||||
p.Blog = appConfig.DefaultBlog
|
||||
}
|
||||
if _, ok := appConfig.Blogs[p.Blog]; !ok {
|
||||
return errors.New("blog doesn't exist")
|
||||
}
|
||||
// Check if section exists
|
||||
if _, ok := appConfig.Blogs[p.Blog].Sections[p.Section]; p.Section != "" && !ok {
|
||||
return errors.New("section doesn't exist")
|
||||
}
|
||||
// Check path
|
||||
p.Path = strings.TrimSuffix(p.Path, "/")
|
||||
if p.Path == "" {
|
||||
|
|
|
@ -30,6 +30,7 @@ const templateTaxonomy = "taxonomy"
|
|||
const templateSearch = "search"
|
||||
const templateSummary = "summary"
|
||||
const templatePhotosSummary = "photosummary"
|
||||
const templateEditor = "editor"
|
||||
|
||||
var templates map[string]*template.Template
|
||||
var templateFunctions template.FuncMap
|
||||
|
@ -229,6 +230,9 @@ func render(w http.ResponseWriter, template string, data *renderData) {
|
|||
}
|
||||
data.Blog = appConfig.Blogs[data.blogString]
|
||||
}
|
||||
if data.Data == nil {
|
||||
data.Data = map[string]interface{}{}
|
||||
}
|
||||
// We need to use a buffer here to enable minification
|
||||
var buffer bytes.Buffer
|
||||
err := templates[template].ExecuteTemplate(&buffer, template, data)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
{{ define "title" }}
|
||||
<title>{{ string .Blog.Lang "editor" }} - {{ .Blog.Title }}</title>
|
||||
{{ end }}
|
||||
|
||||
{{ define "main" }}
|
||||
<main>
|
||||
<h1>{{ string .Blog.Lang "editor" }}</h1>
|
||||
<h2>{{ string .Blog.Lang "create" }}</h2>
|
||||
<form class="fw-form p" method="post">
|
||||
<input type="hidden" name="h" value="entry">
|
||||
<textarea class="fw" name="content"></textarea>
|
||||
<input class="fw" type="submit" value="{{ string .Blog.Lang "create" }}">
|
||||
</form>
|
||||
<h2>{{ string .Blog.Lang "update" }}</h2>
|
||||
<form class="fw-form p" method="post">
|
||||
{{ if .Data.UpdatePostURL }}
|
||||
<input type="hidden" name="editoraction" value="updatepost">
|
||||
<input type="hidden" name="url" value="{{ .Data.UpdatePostURL }}">
|
||||
<textarea class="fw" name="content">{{ .Data.UpdatePostContent }}</textarea>
|
||||
{{ else }}
|
||||
<input type="hidden" name="editoraction" value="loadupdate">
|
||||
<input class="fw" type="text" style="margin-bottom: 5px" name="url" placeholder="URL">
|
||||
{{ end }}
|
||||
<input class="fw" type="submit" value="{{ string .Blog.Lang "update" }}">
|
||||
</form>
|
||||
<h2>{{ string .Blog.Lang "delete" }}</h2>
|
||||
<form class="fw-form p" method="post">
|
||||
<input type="hidden" name="action" value="delete">
|
||||
<input class="fw" type="text" style="margin-bottom: 5px" name="url" placeholder="URL">
|
||||
<input class="fw" type="submit" value="{{ string .Blog.Lang "delete" }}">
|
||||
</form>
|
||||
</main>
|
||||
{{ end }}
|
||||
|
||||
{{ define "editor" }}
|
||||
{{ template "base" . }}
|
||||
{{ end }}
|
|
@ -22,4 +22,7 @@ anoncomment: "You can also create an anonymous comment."
|
|||
interactions: "Interactions"
|
||||
send: "Send"
|
||||
interactionslabel: "Have you published a response to this? Paste the URL here."
|
||||
search: "Search"
|
||||
search: "Search"
|
||||
editor: "Editor"
|
||||
create: "Create"
|
||||
update: "Update"
|
Loading…
Reference in New Issue