diff --git a/admin/admin.go b/admin/admin.go
index 5ee22c5..ef05f05 100644
--- a/admin/admin.go
+++ b/admin/admin.go
@@ -4,7 +4,6 @@ import (
"fmt"
"github.com/bouncepaw/mycorrhiza/viewutil"
"github.com/gorilla/mux"
- "io"
"log"
"mime"
"net/http"
@@ -12,7 +11,6 @@ import (
"sort"
"github.com/bouncepaw/mycorrhiza/cfg"
- "github.com/bouncepaw/mycorrhiza/l18n"
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util"
)
@@ -87,15 +85,12 @@ func handlerAdminUserEdit(w http.ResponseWriter, rq *http.Request) {
f.Put("group", u.Group)
- var lc = l18n.FromRequest(rq)
- html := AdminUserEdit(u, f, lc)
- html = viewutil.Base(viewutil.MetaFrom(w, rq), fmt.Sprintf(lc.Get("admin.user_title"), u.Name), html)
-
if f.HasError() {
w.WriteHeader(http.StatusBadRequest)
}
w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
- io.WriteString(w, html)
+
+ viewEditUser(viewutil.MetaFrom(w, rq), f, u)
}
func handlerAdminUserDelete(w http.ResponseWriter, rq *http.Request) {
@@ -117,26 +112,17 @@ func handlerAdminUserDelete(w http.ResponseWriter, rq *http.Request) {
}
}
- var lc = l18n.FromRequest(rq)
- html := AdminUserDelete(u, util.NewFormData(), lc)
- html = viewutil.Base(viewutil.MetaFrom(w, rq), fmt.Sprintf(lc.Get("admin.user_title"), u.Name), html)
-
if f.HasError() {
w.WriteHeader(http.StatusBadRequest)
}
w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
- io.WriteString(w, html)
+ viewDeleteUser(viewutil.MetaFrom(w, rq), f, u)
}
func handlerAdminUserNew(w http.ResponseWriter, rq *http.Request) {
- var lc = l18n.FromRequest(rq)
if rq.Method == http.MethodGet {
- // New user form
- html := AdminUserNew(util.NewFormData(), lc)
- html = viewutil.Base(viewutil.MetaFrom(w, rq), lc.Get("admin.newuser_title"), html)
-
w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
- io.WriteString(w, html)
+ viewNewUser(viewutil.MetaFrom(w, rq), util.NewFormData())
} else if rq.Method == http.MethodPost {
// Create a user
f := util.FormDataFromRequest(rq, []string{"name", "password", "group"})
@@ -144,12 +130,9 @@ func handlerAdminUserNew(w http.ResponseWriter, rq *http.Request) {
err := user.Register(f.Get("name"), f.Get("password"), f.Get("group"), "local", true)
if err != nil {
- html := AdminUserNew(f.WithError(err), lc)
- html = viewutil.Base(viewutil.MetaFrom(w, rq), lc.Get("admin.newuser_title"), html)
-
w.WriteHeader(http.StatusBadRequest)
w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
- io.WriteString(w, html)
+ viewNewUser(viewutil.MetaFrom(w, rq), f.WithError(err))
} else {
http.Redirect(w, rq, "/admin/users/", http.StatusSeeOther)
}
diff --git a/admin/admin.qtpl b/admin/admin.qtpl
deleted file mode 100644
index 368eeaf..0000000
--- a/admin/admin.qtpl
+++ /dev/null
@@ -1,105 +0,0 @@
-{% import "fmt" %}
-{% import "github.com/bouncepaw/mycorrhiza/l18n" %}
-{% import "github.com/bouncepaw/mycorrhiza/user" %}
-{% import "github.com/bouncepaw/mycorrhiza/util" %}
-
-{% func AdminUserNew(f util.FormData, lc *l18n.Localizer) %}
-
- {%s lc.Get("admin.newuser_title") %}
-
- {% if f.HasError() %}
-
- {%s lc.Get("ui.error") %}:
- {%s f.Error() %}
-
- {% endif %}
-
-
-
-{% endfunc %}
-
-{% func AdminUserEdit(u *user.User, f util.FormData, lc *l18n.Localizer) %}
-
-
- ←
- {%s u.Name %}
-
-
- {%s lc.Get("admin.user_group_heading") %}
-
- {% if f.HasError() %}
-
- {%s lc.Get("ui.error") %}:
- {%s f.Error() %}
-
- {% endif %}
-
-
-
- {%s lc.Get("admin.user_delete_heading") %}
- {%s lc.Get("admin.user_delete_tip") %}
- {%s lc.Get("admin.user_delete") %}
-
-{% endfunc %}
-
-{% func AdminUserDelete(u *user.User, f util.FormData, lc *l18n.Localizer) %}
-
- {%s lc.Get("admin.user_delete_heading") %}
-
- {% if f.HasError() %}
-
- {%s lc.Get("ui.error") %}:
- {%s f.Error() %}
-
- {% endif %}
-
- {%s= lc.Get("admin.user_delete_warn", &l18n.Replacements{"name": fmt.Sprintf("%s", u.Name)}) %}
-
-
-
-{% endfunc %}
diff --git a/admin/admin.qtpl.go b/admin/admin.qtpl.go
deleted file mode 100644
index c7a380e..0000000
--- a/admin/admin.qtpl.go
+++ /dev/null
@@ -1,436 +0,0 @@
-// Code generated by qtc from "admin.qtpl". DO NOT EDIT.
-// See https://github.com/valyala/quicktemplate for details.
-
-//line admin/admin.qtpl:1
-package admin
-
-//line admin/admin.qtpl:1
-import "fmt"
-
-//line admin/admin.qtpl:2
-import "github.com/bouncepaw/mycorrhiza/l18n"
-
-//line admin/admin.qtpl:3
-import "github.com/bouncepaw/mycorrhiza/user"
-
-//line admin/admin.qtpl:4
-import "github.com/bouncepaw/mycorrhiza/util"
-
-//line admin/admin.qtpl:6
-import (
- qtio422016 "io"
-
- qt422016 "github.com/valyala/quicktemplate"
-)
-
-//line admin/admin.qtpl:6
-var (
- _ = qtio422016.Copy
- _ = qt422016.AcquireByteBuffer
-)
-
-//line admin/admin.qtpl:6
-func StreamAdminUserNew(qw422016 *qt422016.Writer, f util.FormData, lc *l18n.Localizer) {
-//line admin/admin.qtpl:6
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:8
- qw422016.E().S(lc.Get("admin.newuser_title"))
-//line admin/admin.qtpl:8
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:10
- if f.HasError() {
-//line admin/admin.qtpl:10
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:12
- qw422016.E().S(lc.Get("ui.error"))
-//line admin/admin.qtpl:12
- qw422016.N().S(`:
- `)
-//line admin/admin.qtpl:13
- qw422016.E().S(f.Error())
-//line admin/admin.qtpl:13
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:15
- }
-//line admin/admin.qtpl:15
- qw422016.N().S(`
-
-
-
-`)
-//line admin/admin.qtpl:47
-}
-
-//line admin/admin.qtpl:47
-func WriteAdminUserNew(qq422016 qtio422016.Writer, f util.FormData, lc *l18n.Localizer) {
-//line admin/admin.qtpl:47
- qw422016 := qt422016.AcquireWriter(qq422016)
-//line admin/admin.qtpl:47
- StreamAdminUserNew(qw422016, f, lc)
-//line admin/admin.qtpl:47
- qt422016.ReleaseWriter(qw422016)
-//line admin/admin.qtpl:47
-}
-
-//line admin/admin.qtpl:47
-func AdminUserNew(f util.FormData, lc *l18n.Localizer) string {
-//line admin/admin.qtpl:47
- qb422016 := qt422016.AcquireByteBuffer()
-//line admin/admin.qtpl:47
- WriteAdminUserNew(qb422016, f, lc)
-//line admin/admin.qtpl:47
- qs422016 := string(qb422016.B)
-//line admin/admin.qtpl:47
- qt422016.ReleaseByteBuffer(qb422016)
-//line admin/admin.qtpl:47
- return qs422016
-//line admin/admin.qtpl:47
-}
-
-//line admin/admin.qtpl:49
-func StreamAdminUserEdit(qw422016 *qt422016.Writer, u *user.User, f util.FormData, lc *l18n.Localizer) {
-//line admin/admin.qtpl:49
- qw422016.N().S(`
-
-
- ←
- `)
-//line admin/admin.qtpl:53
- qw422016.E().S(u.Name)
-//line admin/admin.qtpl:53
- qw422016.N().S(`
-
-
- `)
-//line admin/admin.qtpl:56
- qw422016.E().S(lc.Get("admin.user_group_heading"))
-//line admin/admin.qtpl:56
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:58
- if f.HasError() {
-//line admin/admin.qtpl:58
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:60
- qw422016.E().S(lc.Get("ui.error"))
-//line admin/admin.qtpl:60
- qw422016.N().S(`:
- `)
-//line admin/admin.qtpl:61
- qw422016.E().S(f.Error())
-//line admin/admin.qtpl:61
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:63
- }
-//line admin/admin.qtpl:63
- qw422016.N().S(`
-
-
-
- `)
-//line admin/admin.qtpl:81
- qw422016.E().S(lc.Get("admin.user_delete_heading"))
-//line admin/admin.qtpl:81
- qw422016.N().S(`
- `)
-//line admin/admin.qtpl:82
- qw422016.E().S(lc.Get("admin.user_delete_tip"))
-//line admin/admin.qtpl:82
- qw422016.N().S(`
- `)
-//line admin/admin.qtpl:83
- qw422016.E().S(lc.Get("admin.user_delete"))
-//line admin/admin.qtpl:83
- qw422016.N().S(`
-
-`)
-//line admin/admin.qtpl:85
-}
-
-//line admin/admin.qtpl:85
-func WriteAdminUserEdit(qq422016 qtio422016.Writer, u *user.User, f util.FormData, lc *l18n.Localizer) {
-//line admin/admin.qtpl:85
- qw422016 := qt422016.AcquireWriter(qq422016)
-//line admin/admin.qtpl:85
- StreamAdminUserEdit(qw422016, u, f, lc)
-//line admin/admin.qtpl:85
- qt422016.ReleaseWriter(qw422016)
-//line admin/admin.qtpl:85
-}
-
-//line admin/admin.qtpl:85
-func AdminUserEdit(u *user.User, f util.FormData, lc *l18n.Localizer) string {
-//line admin/admin.qtpl:85
- qb422016 := qt422016.AcquireByteBuffer()
-//line admin/admin.qtpl:85
- WriteAdminUserEdit(qb422016, u, f, lc)
-//line admin/admin.qtpl:85
- qs422016 := string(qb422016.B)
-//line admin/admin.qtpl:85
- qt422016.ReleaseByteBuffer(qb422016)
-//line admin/admin.qtpl:85
- return qs422016
-//line admin/admin.qtpl:85
-}
-
-//line admin/admin.qtpl:87
-func StreamAdminUserDelete(qw422016 *qt422016.Writer, u *user.User, f util.FormData, lc *l18n.Localizer) {
-//line admin/admin.qtpl:87
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:89
- qw422016.E().S(lc.Get("admin.user_delete_heading"))
-//line admin/admin.qtpl:89
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:91
- if f.HasError() {
-//line admin/admin.qtpl:91
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:93
- qw422016.E().S(lc.Get("ui.error"))
-//line admin/admin.qtpl:93
- qw422016.N().S(`:
- `)
-//line admin/admin.qtpl:94
- qw422016.E().S(f.Error())
-//line admin/admin.qtpl:94
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:96
- }
-//line admin/admin.qtpl:96
- qw422016.N().S(`
-
- `)
-//line admin/admin.qtpl:98
- qw422016.N().S(lc.Get("admin.user_delete_warn", &l18n.Replacements{"name": fmt.Sprintf("%s", u.Name)}))
-//line admin/admin.qtpl:98
- qw422016.N().S(`
-
-
-
-`)
-//line admin/admin.qtpl:105
-}
-
-//line admin/admin.qtpl:105
-func WriteAdminUserDelete(qq422016 qtio422016.Writer, u *user.User, f util.FormData, lc *l18n.Localizer) {
-//line admin/admin.qtpl:105
- qw422016 := qt422016.AcquireWriter(qq422016)
-//line admin/admin.qtpl:105
- StreamAdminUserDelete(qw422016, u, f, lc)
-//line admin/admin.qtpl:105
- qt422016.ReleaseWriter(qw422016)
-//line admin/admin.qtpl:105
-}
-
-//line admin/admin.qtpl:105
-func AdminUserDelete(u *user.User, f util.FormData, lc *l18n.Localizer) string {
-//line admin/admin.qtpl:105
- qb422016 := qt422016.AcquireByteBuffer()
-//line admin/admin.qtpl:105
- WriteAdminUserDelete(qb422016, u, f, lc)
-//line admin/admin.qtpl:105
- qs422016 := string(qb422016.B)
-//line admin/admin.qtpl:105
- qt422016.ReleaseByteBuffer(qb422016)
-//line admin/admin.qtpl:105
- return qs422016
-//line admin/admin.qtpl:105
-}
diff --git a/admin/view.go b/admin/view.go
index ec22ae2..f4318fc 100644
--- a/admin/view.go
+++ b/admin/view.go
@@ -4,6 +4,7 @@ import (
"embed"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/user"
+ "github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/viewutil"
"github.com/gorilla/mux"
"net/http"
@@ -28,13 +29,25 @@ const adminTranslationRu = `
{{define "registered at"}}Зарегистрирован{{end}}
{{define "actions"}}Действия{{end}}
{{define "edit"}}Изменить{{end}}
+
+{{define "new user"}}Новый пользователь{{end}}
+{{define "password"}}Пароль{{end}}
+{{define "create"}}Создать{{end}}
+
+{{define "change group"}}Изменить группу{{end}}
+{{define "user x"}}Пользователь {{.}}{{end}}
+{{define "update"}}Обновить{{end}}
+{{define "delete user"}}Удалить пользователя{{end}}
+{{define "delete user tip"}}Удаляет пользователя из базы данных. Правки пользователя будут сохранены. Имя пользователя освободится для повторной регистрации.{{end}}
+
+{{define "delete user?"}}Удалить пользователя {{.}}?{{end}}
+{{define "delete user warning"}}Вы уверены, что хотите удалить этого пользователя из базы данных? Это действие нельзя отменить.{{end}}
`
var (
//go:embed *.html
- fs embed.FS
- panelChain viewutil.Chain
- listChain viewutil.Chain
+ fs embed.FS
+ panelChain, listChain, newUserChain, editUserChain, deleteUserChain viewutil.Chain
)
func Init(rtr *mux.Router) {
@@ -50,6 +63,9 @@ func Init(rtr *mux.Router) {
panelChain = viewutil.CopyEnRuWith(fs, "view_panel.html", adminTranslationRu)
listChain = viewutil.CopyEnRuWith(fs, "view_user_list.html", adminTranslationRu)
+ newUserChain = viewutil.CopyEnRuWith(fs, "view_new_user.html", adminTranslationRu)
+ editUserChain = viewutil.CopyEnRuWith(fs, "view_edit_user.html", adminTranslationRu)
+ deleteUserChain = viewutil.CopyEnRuWith(fs, "view_delete_user.html", adminTranslationRu)
}
func viewPanel(meta viewutil.Meta) {
@@ -69,3 +85,37 @@ func viewList(meta viewutil.Meta, users []*user.User) {
Users: users,
})
}
+
+type newUserData struct {
+ *viewutil.BaseData
+ Form util.FormData
+}
+
+func viewNewUser(meta viewutil.Meta, form util.FormData) {
+ viewutil.ExecutePage(meta, newUserChain, newUserData{
+ BaseData: &viewutil.BaseData{},
+ Form: form,
+ })
+}
+
+type editDeleteUserData struct {
+ *viewutil.BaseData
+ Form util.FormData
+ U *user.User
+}
+
+func viewEditUser(meta viewutil.Meta, form util.FormData, u *user.User) {
+ viewutil.ExecutePage(meta, editUserChain, editDeleteUserData{
+ BaseData: &viewutil.BaseData{},
+ Form: form,
+ U: u,
+ })
+}
+
+func viewDeleteUser(meta viewutil.Meta, form util.FormData, u *user.User) {
+ viewutil.ExecutePage(meta, deleteUserChain, editDeleteUserData{
+ BaseData: &viewutil.BaseData{},
+ Form: form,
+ U: u,
+ })
+}
diff --git a/admin/view_delete_user.html b/admin/view_delete_user.html
new file mode 100644
index 0000000..bec071b
--- /dev/null
+++ b/admin/view_delete_user.html
@@ -0,0 +1,21 @@
+{{define "delete user?"}}Delete user {{.}}?{{end}}
+{{define "title"}}{{template "delete user?" .U.Name}}{{end}}
+{{define "body"}}
+
+ {{template "delete user?" .U.Name}}
+
+ {{if .Form.HasError}}
+
+ {{template "error"}}:
+ {{.Form.Error}}
+
+ {{end}}
+
+ {{block "delete user warning" .}}Are you sure you want to delete them from the database? This action is irreversible.{{end}}
+
+
+
+{{end}}
\ No newline at end of file
diff --git a/admin/view_edit_user.html b/admin/view_edit_user.html
new file mode 100644
index 0000000..5afe812
--- /dev/null
+++ b/admin/view_edit_user.html
@@ -0,0 +1,39 @@
+{{define "user x"}}User {{.}}{{end}}
+{{define "title"}}{{template "user x" .U.Name}}{{end}}
+{{define "body"}}
+
+
+ ←
+ {{.U.Name}}
+
+
+ {{block "change group" .}}Change group{{end}}
+
+ {{if .Form.HasError}}
+
+ {{template "error"}}:
+ {{.Form.Error}}
+
+ {{end}}
+
+
+
+ {{block "delete user" .}}Delete user{{end}}
+ {{block "delete user tip" .}}Remove the user from the database. Changes made by the user will be preserved. It will be possible to take this username later.{{end}}
+ {{template "delete"}}
+
+{{end}}
\ No newline at end of file
diff --git a/admin/view_new_user.html b/admin/view_new_user.html
new file mode 100644
index 0000000..5be70b7
--- /dev/null
+++ b/admin/view_new_user.html
@@ -0,0 +1,43 @@
+{{define "title"}}{{block "create user" .}}Create a new user{{end}}{{end}}
+{{define "body"}}
+
+ {{block "new user" .}}New user{{end}}
+
+ {{if .Form.HasError}}
+
+ {{template "error"}}:
+ {{.Form.Error}}
+
+ {{end}}
+
+
+
+{{end}}
\ No newline at end of file
diff --git a/l18n/en/admin.json b/l18n/en/admin.json
deleted file mode 100644
index afa173c..0000000
--- a/l18n/en/admin.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "users_title": "Manage users",
- "users_create": "Create a new user",
- "users_reindex": "Reindex users",
- "users_name": "Name",
- "users_password": "Password",
- "users_group": "Group",
- "users_registered": "Registered at",
- "users_actions": "Actions",
- "users_notime": "unknown",
- "users_edit": "Edit",
-
- "user_title": "User %s",
- "user_group_heading": "Change group",
- "user_update": "Update",
- "user_delete_heading": "Delete user",
- "user_delete_tip": "Remove the user from the database. Changes made by the user will be preserved. It will be possible to take this username later.",
- "user_delete_warn": "Are you sure you want to delete {{.name}} from the database? This action is irreversible.",
- "user_delete": "Delete",
-
- "newuser_title": "New user",
- "newuser_create": "Create"
-}
diff --git a/l18n/ru/admin.json b/l18n/ru/admin.json
deleted file mode 100644
index aacd0f3..0000000
--- a/l18n/ru/admin.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "users_title": "Менеджер пользователей",
- "users_create": "Создать пользователя",
- "users_reindex": "Переиндексировать пользователей",
- "users_name": "Имя",
- "users_password": "Пароль",
- "users_group": "Группа",
- "users_registered": "Время создания",
- "users_actions": "Действия",
- "users_notime": "неизвестно",
- "users_edit": "Изменить",
-
- "user_title": "Пользователь %s",
- "user_group_heading": "Изменить группу",
- "user_update": "Обновить",
- "user_delete_heading": "Удалить пользователя",
- "user_delete_tip": "Удаляет пользователя из базы данных. Правки пользователя будут сохранены. Имя пользователя освободится для повторной регистрации.",
- "user_delete_warn": "Вы уверены, что хотите удалить {{.name}} из базы данных? Это действие нельзя отменить.",
- "user_delete": "Удалить",
-
- "newuser_title": "Новый пользователь",
- "newuser_create": "Создать"
-}
diff --git a/main.go b/main.go
index 34b1652..ad764f1 100644
--- a/main.go
+++ b/main.go
@@ -3,7 +3,6 @@
//go:generate go run github.com/valyala/quicktemplate/qtc -dir=mycoopts
//go:generate go run github.com/valyala/quicktemplate/qtc -dir=auth
//go:generate go run github.com/valyala/quicktemplate/qtc -dir=hypview
-//go:generate go run github.com/valyala/quicktemplate/qtc -dir=admin
// Command mycorrhiza is a program that runs a mycorrhiza wiki.
package main
diff --git a/static/default.css b/static/default.css
index a9aef10..663ca91 100644
--- a/static/default.css
+++ b/static/default.css
@@ -502,6 +502,8 @@ kbd {
border: 1px dashed #999;
}
+a.btn_destructive,
+a.btn_destructive:visited,
.btn_destructive {
border-color: #aa1818;
background-color: #ee4343;
diff --git a/viewutil/base.html b/viewutil/base.html
index d24a537..4363416 100644
--- a/viewutil/base.html
+++ b/viewutil/base.html
@@ -1,6 +1,8 @@
{{define "confirm"}}Confirm{{end}}
{{define "cancel"}}Cancel{{end}}
{{define "save"}}Save{{end}}
+{{define "error"}}Error{{end}}
+{{define "delete"}}Delete{{end}}
{{define "page"}}
diff --git a/viewutil/viewutil.go b/viewutil/viewutil.go
index 133a51a..59ec00c 100644
--- a/viewutil/viewutil.go
+++ b/viewutil/viewutil.go
@@ -28,6 +28,8 @@ const ruText = `
{{define "confirm"}}Подтвердить{{end}}
{{define "cancel"}}Отмена{{end}}
{{define "save"}}Сохранить{{end}}
+{{define "error"}}Ошибка{{end}}
+{{define "delete"}}Удалить{{end}}
`
func Init() {