mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-12-04 18:19:54 +00:00
Implement /edit-category
Also, /remove-from-category now accepts multiple hyphae at once, and removes them all
This commit is contained in:
parent
827c9a0005
commit
3ff57d1d03
@ -16,10 +16,22 @@ func InitHandlers(r *mux.Router) {
|
||||
r.PathPrefix("/add-to-category").HandlerFunc(handlerAddToCategory).Methods("POST")
|
||||
r.PathPrefix("/remove-from-category").HandlerFunc(handlerRemoveFromCategory).Methods("POST")
|
||||
r.PathPrefix("/category/").HandlerFunc(handlerCategory).Methods("GET")
|
||||
r.PathPrefix("/edit-category/").HandlerFunc(handlerEditCategory).Methods("GET")
|
||||
r.PathPrefix("/category").HandlerFunc(handlerListCategory).Methods("GET")
|
||||
prepareViews()
|
||||
}
|
||||
|
||||
func handlerEditCategory(w http.ResponseWriter, rq *http.Request) {
|
||||
util.PrepareRq(rq)
|
||||
catName := util.CanonicalName(strings.TrimPrefix(strings.TrimPrefix(rq.URL.Path, "/edit-category"), "/"))
|
||||
if catName == "" {
|
||||
http.Error(w, "No category name", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
log.Println("Editing category", catName)
|
||||
categoryEdit(viewutil.MetaFrom(w, rq), catName)
|
||||
}
|
||||
|
||||
func handlerListCategory(w http.ResponseWriter, rq *http.Request) {
|
||||
log.Println("Viewing list of categories")
|
||||
categoryList(viewutil.MetaFrom(w, rq))
|
||||
@ -36,24 +48,54 @@ func handlerCategory(w http.ResponseWriter, rq *http.Request) {
|
||||
categoryPage(viewutil.MetaFrom(w, rq), catName)
|
||||
}
|
||||
|
||||
// A request for removal of hyphae can either remove one hypha (used in the card on /hypha) or many hyphae (used in /edit-category). Both approaches are handled by /remove-from-category. This function finds all passed hyphae.
|
||||
//
|
||||
// There is one hypha from the hypha field. Then there are n hyphae in fields prefixed by _. It seems like I have to do it myself. Compare with PHP which handles it for you. I hope I am doing this wrong.
|
||||
func hyphaeFromRequest(rq *http.Request) (canonicalNames []string) {
|
||||
if err := rq.ParseForm(); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
if hyphaName := util.CanonicalName(rq.PostFormValue("hypha")); hyphaName != "" {
|
||||
canonicalNames = append(canonicalNames, hyphaName)
|
||||
}
|
||||
// According to https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox,
|
||||
//
|
||||
// > If a checkbox is unchecked when its form is submitted, there is no value submitted to the server to represent its unchecked state
|
||||
//
|
||||
// It means, that if there is a value, it is checked. And we can ignore values altogether.
|
||||
for key, _ := range rq.PostForm {
|
||||
// No prefix or "_":
|
||||
if !strings.HasPrefix(key, "_") || len(key) == 1 {
|
||||
continue
|
||||
}
|
||||
canonicalNames = append(canonicalNames, util.CanonicalName(key[1:]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func handlerRemoveFromCategory(w http.ResponseWriter, rq *http.Request) {
|
||||
util.PrepareRq(rq)
|
||||
var (
|
||||
hyphaName = util.CanonicalName(rq.PostFormValue("hypha"))
|
||||
u = user.FromRequest(rq)
|
||||
hyphaNames = hyphaeFromRequest(rq)
|
||||
catName = util.CanonicalName(rq.PostFormValue("cat"))
|
||||
redirectTo = rq.PostFormValue("redirect-to")
|
||||
)
|
||||
if !user.FromRequest(rq).CanProceed("remove-from-category") {
|
||||
if !u.CanProceed("remove-from-category") {
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
_, _ = io.WriteString(w, "403 Forbidden")
|
||||
return
|
||||
}
|
||||
if hyphaName == "" || catName == "" {
|
||||
if len(hyphaNames) == 0 || catName == "" {
|
||||
log.Printf("%s passed no data for removal of hyphae from a category\n", u.Name)
|
||||
http.Redirect(w, rq, redirectTo, http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
log.Println(user.FromRequest(rq).Name, "removed", hyphaName, "from", catName)
|
||||
removeHyphaFromCategory(hyphaName, catName)
|
||||
for _, hyphaName := range hyphaNames {
|
||||
// TODO: Make it more effective.
|
||||
removeHyphaFromCategory(hyphaName, catName)
|
||||
}
|
||||
log.Printf("%s removed %q from category %s\n", u.Name, hyphaNames, catName)
|
||||
http.Redirect(w, rq, redirectTo, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
35
categories/view_edit.html
Normal file
35
categories/view_edit.html
Normal file
@ -0,0 +1,35 @@
|
||||
{{define "edit category x"}}Edit category {{beautifulName .}}{{end}}
|
||||
{{define "title"}}{{template "edit category x" .CatName}}{{end}}
|
||||
{{define "body"}}
|
||||
<main class="main-width category">
|
||||
<h1>{{block "edit category heading" .CatName}}Edit category <a href="/category/{{.}}">{{beautifulName .}}</a>{{end}}</h1>
|
||||
{{if len .Hyphae | not}}
|
||||
<p>{{block "empty cat" .}}This category is empty{{end}}</p>
|
||||
{{end}}
|
||||
|
||||
{{if .GivenPermissionToModify}}
|
||||
<h2>{{block "add hypha" .}}Add a hypha to the category{{end}}</h2>
|
||||
<form method="POST" action="/add-to-category" class="category__add-form">
|
||||
<input type="text" name="hypha" id="_hypha-name"
|
||||
placeholder="{{block `hypha name` .}}Hypha name{{end}}">
|
||||
<input type="hidden" name="cat" value="{{.CatName}}">
|
||||
<input type="hidden" name="redirect-to" value="/category/{{.CatName}}">
|
||||
<input type="submit" class="btn" value="{{block `add` .}}Add{{end}}">
|
||||
</form>
|
||||
|
||||
{{if len .Hyphae}}
|
||||
<h2>{{block "remove hyphae" .}}Remove hyphae from the category{{end}}</h2>
|
||||
<form method="POST" action="/remove-from-category" class="multi-remove-from-category">
|
||||
{{range .Hyphae}}
|
||||
<input type="checkbox" name="_{{.}}" id="_{{.}}">
|
||||
<label for="_{{.}}"><a href="/hypha/{{.}}">{{beautifulName .}}</a></label>
|
||||
<br>
|
||||
{{end}}
|
||||
<input type="hidden" name="cat" value="{{.CatName}}">
|
||||
<input type="hidden" name="redirect-to" value="/edit-category/{{.CatName}}">
|
||||
<input type="submit" class="btn" value="{{block `remove` .}}Remove{{end}}">
|
||||
</form>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</main>
|
||||
{{end}}
|
@ -3,6 +3,11 @@
|
||||
{{define "body"}}
|
||||
{{$catName := .CatName}}
|
||||
<main class="main-width category">
|
||||
{{if .GivenPermissionToModify}}
|
||||
<div class="btn btn_navititle">
|
||||
<a class="btn__link_navititle" href="/edit-category/{{$catName}}">{{block "edit" .}}Edit{{end}}</a>
|
||||
</div>
|
||||
{{end}}
|
||||
<h1>{{block "cat" .}}Category{{end}} <i>{{beautifulName $catName}}</i></h1>
|
||||
{{if len .Hyphae | not}}
|
||||
<p>{{block "empty cat" .}}This category is empty{{end}}</p>
|
||||
|
@ -24,14 +24,15 @@ const ruTranslation = `
|
||||
|
||||
var (
|
||||
//go:embed *.html
|
||||
fs embed.FS
|
||||
viewListChain, viewPageChain, viewCardChain viewutil.Chain
|
||||
fs embed.FS
|
||||
viewListChain, viewPageChain, viewCardChain, viewEditChain viewutil.Chain
|
||||
)
|
||||
|
||||
func prepareViews() {
|
||||
viewCardChain = viewutil.CopyEnRuWith(fs, "view_card.html", ruTranslation)
|
||||
viewListChain = viewutil.CopyEnRuWith(fs, "view_list.html", ruTranslation)
|
||||
viewPageChain = viewutil.CopyEnRuWith(fs, "view_page.html", ruTranslation)
|
||||
viewEditChain = viewutil.CopyEnRuWith(fs, "view_edit.html", ruTranslation)
|
||||
}
|
||||
|
||||
type cardData struct {
|
||||
@ -54,15 +55,26 @@ func CategoryCard(meta viewutil.Meta, hyphaName string) string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
type pageData struct {
|
||||
type catData struct {
|
||||
*viewutil.BaseData
|
||||
CatName string
|
||||
Hyphae []string
|
||||
GivenPermissionToModify bool
|
||||
}
|
||||
|
||||
func categoryEdit(meta viewutil.Meta, catName string) {
|
||||
viewutil.ExecutePage(meta, viewEditChain, catData{
|
||||
BaseData: &viewutil.BaseData{
|
||||
Addr: "/edit-category/" + catName,
|
||||
},
|
||||
CatName: catName,
|
||||
Hyphae: hyphaeInCategory(catName),
|
||||
GivenPermissionToModify: meta.U.CanProceed("add-to-category"),
|
||||
})
|
||||
}
|
||||
|
||||
func categoryPage(meta viewutil.Meta, catName string) {
|
||||
viewutil.ExecutePage(meta, viewPageChain, pageData{
|
||||
viewutil.ExecutePage(meta, viewPageChain, catData{
|
||||
BaseData: &viewutil.BaseData{
|
||||
Addr: "/category/" + catName,
|
||||
},
|
||||
|
@ -35,8 +35,8 @@ var minimalRights = map[string]int{
|
||||
"edit": 1,
|
||||
"upload-binary": 1,
|
||||
"upload-text": 1,
|
||||
"add-to-category": 1,
|
||||
"remove-from-category": 1,
|
||||
"add-to-category": 2,
|
||||
"remove-from-category": 2,
|
||||
"rename": 2,
|
||||
"remove-media": 2,
|
||||
"update-header-links": 3,
|
||||
|
Loading…
Reference in New Issue
Block a user