From 4ede2783c5ef00380fc6301ffc6b25fbd6d03e91 Mon Sep 17 00:00:00 2001 From: Umar Getagazov Date: Fri, 19 Aug 2022 22:24:59 +0300 Subject: [PATCH] Migrate /edit to html/template --- hypview/hypview.go | 64 +++++- hypview/mutators.qtpl | 123 ----------- hypview/mutators.qtpl.go | 452 --------------------------------------- hypview/view_edit.html | 104 +++++++++ static/default.css | 2 +- viewutil/viewutil.go | 7 +- web/mutators.go | 88 ++++---- 7 files changed, 210 insertions(+), 630 deletions(-) delete mode 100644 hypview/mutators.qtpl delete mode 100644 hypview/mutators.qtpl.go create mode 100644 hypview/view_edit.html diff --git a/hypview/hypview.go b/hypview/hypview.go index 216aebc..d284c37 100644 --- a/hypview/hypview.go +++ b/hypview/hypview.go @@ -2,16 +2,51 @@ package hypview import ( "embed" - "github.com/bouncepaw/mycorrhiza/cfg" - "github.com/bouncepaw/mycorrhiza/viewutil" + "html/template" "log" "strings" + + "github.com/bouncepaw/mycorrhiza/cfg" + "github.com/bouncepaw/mycorrhiza/viewutil" ) var ( //go:embed *.html fs embed.FS ruTranslation = ` +{{define "editing hypha"}}Редактирование {{beautifulName .}}{{end}} +{{define "editing [[hypha]]"}}Редактирование {{beautifulName .}}{{end}} +{{define "you're creating a new hypha"}}Вы создаёте новую гифу.{{end}} +{{define "describe your changes"}}Опишите ваши правки{{end}} +{{define "save"}}Сохранить{{end}} +{{define "preview"}}Предпросмотр{{end}} +{{define "previewing hypha"}}Предпросмотр «{{beautifulName .}}»{{end}} +{{define "preview tip"}}Заметьте, эта гифа ещё не сохранена. Вот её предпросмотр:{{end}} + +{{define "markup"}}Разметка{{end}} +{{define "link"}}Ссылка{{end}} +{{define "link title"}}Текст{{end}} +{{define "heading"}}Заголовок{{end}} +{{define "bold"}}Жирный{{end}} +{{define "italic"}}Курсив{{end}} +{{define "highlight"}}Выделение{{end}} +{{define "underline"}}Подчеркивание{{end}} +{{define "mono"}}Моноширинный{{end}} +{{define "super"}}Надстрочный{{end}} +{{define "sub"}}Подстрочный{{end}} +{{define "strike"}}Зачёркнутый{{end}} +{{define "rocket"}}Ссылка-ракета{{end}} +{{define "transclude"}}Трансклюзия{{end}} +{{define "hr"}}Гориз. черта{{end}} +{{define "code"}}Код-блок{{end}} +{{define "bullets"}}Маркир. список{{end}} +{{define "numbers"}}Нумер. список{{end}} +{{define "mycomarkup help"}}Подробнее о микоразметке{{end}} +{{define "actions"}}Действия{{end}} +{{define "current date"}}Текущая дата{{end}} +{{define "current time"}}Текущее время{{end}} +{{define "selflink"}}Ссылка на вас{{end}} + {{define "empty heading"}}Эта гифа не существует{{end}} {{define "empty no rights"}}У вас нет прав для создания новых гиф. Вы можете:{{end}} {{define "empty log in"}}Войти в свою учётную запись, если она у вас есть{{end}} @@ -37,6 +72,7 @@ var ( {{define "leave redirections"}}Оставить перенаправления{{end}} ` chainNaviTitle viewutil.Chain + chainEditHypha viewutil.Chain chainEmptyHypha viewutil.Chain chainDeleteHypha viewutil.Chain chainRenameHypha viewutil.Chain @@ -44,11 +80,35 @@ var ( func Init() { chainNaviTitle = viewutil.CopyEnRuWith(fs, "view_navititle.html", "") + chainEditHypha = viewutil.CopyEnRuWith(fs, "view_edit.html", ruTranslation) chainEmptyHypha = viewutil.CopyEnRuWith(fs, "view_empty_hypha.html", ruTranslation) chainDeleteHypha = viewutil.CopyEnRuWith(fs, "view_delete.html", ruTranslation) chainRenameHypha = viewutil.CopyEnRuWith(fs, "view_rename.html", ruTranslation) } +type editData struct { + *viewutil.BaseData + HyphaName string + IsNew bool + Content string + Message string + Preview template.HTML +} + +func EditHypha(meta viewutil.Meta, hyphaName string, isNew bool, content string, message string, preview template.HTML) { + viewutil.ExecutePage(meta, chainEditHypha, editData{ + BaseData: &viewutil.BaseData{ + Addr: "/edit/" + hyphaName, + EditScripts: cfg.EditScripts, + }, + HyphaName: hyphaName, + IsNew: isNew, + Content: content, + Message: message, + Preview: preview, + }) +} + type deleteRenameData struct { *viewutil.BaseData HyphaName string diff --git a/hypview/mutators.qtpl b/hypview/mutators.qtpl deleted file mode 100644 index bab477d..0000000 --- a/hypview/mutators.qtpl +++ /dev/null @@ -1,123 +0,0 @@ -{% import "fmt" %} -{% import "net/http" %} - -{% import "github.com/bouncepaw/mycorrhiza/cfg" %} -{% import "github.com/bouncepaw/mycorrhiza/l18n" %} -{% import "github.com/bouncepaw/mycorrhiza/user" %} - -{% func Toolbar(u *user.User, lc *l18n.Localizer) %} - - - -{% endfunc %} - -{% func Editor(rq *http.Request, hyphaName, textAreaFill, warning string) %} -{% code - lc := l18n.FromRequest(rq) -%} -
-
-

{%s= fmt.Sprintf(lc.Get("edit.title"), beautifulLink(hyphaName)) %}

- {%s= warning %} - -

- -

-

- - - {%s lc.Get("ui.cancel") %} -

-
-
-{%s= Toolbar(user.FromRequest(rq), lc) %} -{%= editScripts() %} -{% endfunc %} - -{% func Preview(rq *http.Request, hyphaName, textAreaFill, message, warning string, renderedPage string) %} -{% code - lc := l18n.FromRequest(rq) -%} -
-
-

{%s= fmt.Sprintf(lc.Get("edit.title"), beautifulLink(hyphaName)) %}

- {%s= warning %} - -

- -

-

- - - {%s lc.Get("ui.cancel") %} -

-
-

{%s lc.Get("edit.preview_tip") %}

-
{%s= renderedPage %}
-
-{%s= Toolbar(user.FromRequest(rq), lc) %} -{%= editScripts() %} -{% endfunc %} - -{% func editScripts() %} - -{% for _, scriptPath := range cfg.EditScripts %} - -{% endfor %} -{% endfunc %} diff --git a/hypview/mutators.qtpl.go b/hypview/mutators.qtpl.go deleted file mode 100644 index 1200c9c..0000000 --- a/hypview/mutators.qtpl.go +++ /dev/null @@ -1,452 +0,0 @@ -// Code generated by qtc from "mutators.qtpl". DO NOT EDIT. -// See https://github.com/valyala/quicktemplate for details. - -//line hypview/mutators.qtpl:1 -package hypview - -//line hypview/mutators.qtpl:1 -import "fmt" - -//line hypview/mutators.qtpl:2 -import "net/http" - -//line hypview/mutators.qtpl:4 -import "github.com/bouncepaw/mycorrhiza/cfg" - -//line hypview/mutators.qtpl:5 -import "github.com/bouncepaw/mycorrhiza/l18n" - -//line hypview/mutators.qtpl:6 -import "github.com/bouncepaw/mycorrhiza/user" - -//line hypview/mutators.qtpl:8 -import ( - qtio422016 "io" - - qt422016 "github.com/valyala/quicktemplate" -) - -//line hypview/mutators.qtpl:8 -var ( - _ = qtio422016.Copy - _ = qt422016.AcquireByteBuffer -) - -//line hypview/mutators.qtpl:8 -func StreamToolbar(qw422016 *qt422016.Writer, u *user.User, lc *l18n.Localizer) { -//line hypview/mutators.qtpl:8 - qw422016.N().S(` - - - -`) -//line hypview/mutators.qtpl:66 -} - -//line hypview/mutators.qtpl:66 -func WriteToolbar(qq422016 qtio422016.Writer, u *user.User, lc *l18n.Localizer) { -//line hypview/mutators.qtpl:66 - qw422016 := qt422016.AcquireWriter(qq422016) -//line hypview/mutators.qtpl:66 - StreamToolbar(qw422016, u, lc) -//line hypview/mutators.qtpl:66 - qt422016.ReleaseWriter(qw422016) -//line hypview/mutators.qtpl:66 -} - -//line hypview/mutators.qtpl:66 -func Toolbar(u *user.User, lc *l18n.Localizer) string { -//line hypview/mutators.qtpl:66 - qb422016 := qt422016.AcquireByteBuffer() -//line hypview/mutators.qtpl:66 - WriteToolbar(qb422016, u, lc) -//line hypview/mutators.qtpl:66 - qs422016 := string(qb422016.B) -//line hypview/mutators.qtpl:66 - qt422016.ReleaseByteBuffer(qb422016) -//line hypview/mutators.qtpl:66 - return qs422016 -//line hypview/mutators.qtpl:66 -} - -//line hypview/mutators.qtpl:68 -func StreamEditor(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, textAreaFill, warning string) { -//line hypview/mutators.qtpl:68 - qw422016.N().S(` -`) -//line hypview/mutators.qtpl:70 - lc := l18n.FromRequest(rq) - -//line hypview/mutators.qtpl:71 - qw422016.N().S(` -
-
-

`) -//line hypview/mutators.qtpl:75 - qw422016.N().S(fmt.Sprintf(lc.Get("edit.title"), beautifulLink(hyphaName))) -//line hypview/mutators.qtpl:75 - qw422016.N().S(`

- `) -//line hypview/mutators.qtpl:76 - qw422016.N().S(warning) -//line hypview/mutators.qtpl:76 - qw422016.N().S(` - -

- -

-

- - - `) -//line hypview/mutators.qtpl:84 - qw422016.E().S(lc.Get("ui.cancel")) -//line hypview/mutators.qtpl:84 - qw422016.N().S(` -

-
-
-`) -//line hypview/mutators.qtpl:88 - qw422016.N().S(Toolbar(user.FromRequest(rq), lc)) -//line hypview/mutators.qtpl:88 - qw422016.N().S(` -`) -//line hypview/mutators.qtpl:89 - streameditScripts(qw422016) -//line hypview/mutators.qtpl:89 - qw422016.N().S(` -`) -//line hypview/mutators.qtpl:90 -} - -//line hypview/mutators.qtpl:90 -func WriteEditor(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, textAreaFill, warning string) { -//line hypview/mutators.qtpl:90 - qw422016 := qt422016.AcquireWriter(qq422016) -//line hypview/mutators.qtpl:90 - StreamEditor(qw422016, rq, hyphaName, textAreaFill, warning) -//line hypview/mutators.qtpl:90 - qt422016.ReleaseWriter(qw422016) -//line hypview/mutators.qtpl:90 -} - -//line hypview/mutators.qtpl:90 -func Editor(rq *http.Request, hyphaName, textAreaFill, warning string) string { -//line hypview/mutators.qtpl:90 - qb422016 := qt422016.AcquireByteBuffer() -//line hypview/mutators.qtpl:90 - WriteEditor(qb422016, rq, hyphaName, textAreaFill, warning) -//line hypview/mutators.qtpl:90 - qs422016 := string(qb422016.B) -//line hypview/mutators.qtpl:90 - qt422016.ReleaseByteBuffer(qb422016) -//line hypview/mutators.qtpl:90 - return qs422016 -//line hypview/mutators.qtpl:90 -} - -//line hypview/mutators.qtpl:92 -func StreamPreview(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, textAreaFill, message, warning string, renderedPage string) { -//line hypview/mutators.qtpl:92 - qw422016.N().S(` -`) -//line hypview/mutators.qtpl:94 - lc := l18n.FromRequest(rq) - -//line hypview/mutators.qtpl:95 - qw422016.N().S(` -
-
-

`) -//line hypview/mutators.qtpl:99 - qw422016.N().S(fmt.Sprintf(lc.Get("edit.title"), beautifulLink(hyphaName))) -//line hypview/mutators.qtpl:99 - qw422016.N().S(`

- `) -//line hypview/mutators.qtpl:100 - qw422016.N().S(warning) -//line hypview/mutators.qtpl:100 - qw422016.N().S(` - -

- -

-

- - - `) -//line hypview/mutators.qtpl:108 - qw422016.E().S(lc.Get("ui.cancel")) -//line hypview/mutators.qtpl:108 - qw422016.N().S(` -

-
-

`) -//line hypview/mutators.qtpl:111 - qw422016.E().S(lc.Get("edit.preview_tip")) -//line hypview/mutators.qtpl:111 - qw422016.N().S(`

-
`) -//line hypview/mutators.qtpl:112 - qw422016.N().S(renderedPage) -//line hypview/mutators.qtpl:112 - qw422016.N().S(`
-
-`) -//line hypview/mutators.qtpl:114 - qw422016.N().S(Toolbar(user.FromRequest(rq), lc)) -//line hypview/mutators.qtpl:114 - qw422016.N().S(` -`) -//line hypview/mutators.qtpl:115 - streameditScripts(qw422016) -//line hypview/mutators.qtpl:115 - qw422016.N().S(` -`) -//line hypview/mutators.qtpl:116 -} - -//line hypview/mutators.qtpl:116 -func WritePreview(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, textAreaFill, message, warning string, renderedPage string) { -//line hypview/mutators.qtpl:116 - qw422016 := qt422016.AcquireWriter(qq422016) -//line hypview/mutators.qtpl:116 - StreamPreview(qw422016, rq, hyphaName, textAreaFill, message, warning, renderedPage) -//line hypview/mutators.qtpl:116 - qt422016.ReleaseWriter(qw422016) -//line hypview/mutators.qtpl:116 -} - -//line hypview/mutators.qtpl:116 -func Preview(rq *http.Request, hyphaName, textAreaFill, message, warning string, renderedPage string) string { -//line hypview/mutators.qtpl:116 - qb422016 := qt422016.AcquireByteBuffer() -//line hypview/mutators.qtpl:116 - WritePreview(qb422016, rq, hyphaName, textAreaFill, message, warning, renderedPage) -//line hypview/mutators.qtpl:116 - qs422016 := string(qb422016.B) -//line hypview/mutators.qtpl:116 - qt422016.ReleaseByteBuffer(qb422016) -//line hypview/mutators.qtpl:116 - return qs422016 -//line hypview/mutators.qtpl:116 -} - -//line hypview/mutators.qtpl:118 -func streameditScripts(qw422016 *qt422016.Writer) { -//line hypview/mutators.qtpl:118 - qw422016.N().S(` - -`) -//line hypview/mutators.qtpl:120 - for _, scriptPath := range cfg.EditScripts { -//line hypview/mutators.qtpl:120 - qw422016.N().S(` - -`) -//line hypview/mutators.qtpl:122 - } -//line hypview/mutators.qtpl:122 - qw422016.N().S(` -`) -//line hypview/mutators.qtpl:123 -} - -//line hypview/mutators.qtpl:123 -func writeeditScripts(qq422016 qtio422016.Writer) { -//line hypview/mutators.qtpl:123 - qw422016 := qt422016.AcquireWriter(qq422016) -//line hypview/mutators.qtpl:123 - streameditScripts(qw422016) -//line hypview/mutators.qtpl:123 - qt422016.ReleaseWriter(qw422016) -//line hypview/mutators.qtpl:123 -} - -//line hypview/mutators.qtpl:123 -func editScripts() string { -//line hypview/mutators.qtpl:123 - qb422016 := qt422016.AcquireByteBuffer() -//line hypview/mutators.qtpl:123 - writeeditScripts(qb422016) -//line hypview/mutators.qtpl:123 - qs422016 := string(qb422016.B) -//line hypview/mutators.qtpl:123 - qt422016.ReleaseByteBuffer(qb422016) -//line hypview/mutators.qtpl:123 - return qs422016 -//line hypview/mutators.qtpl:123 -} diff --git a/hypview/view_edit.html b/hypview/view_edit.html new file mode 100644 index 0000000..465cdf5 --- /dev/null +++ b/hypview/view_edit.html @@ -0,0 +1,104 @@ +{{define "toolbar"}} + + + +{{end}} + +{{define "editing hypha"}}Edit {{beautifulName .}}{{end}} +{{define "previewing hypha"}}Preview of {{beautifulName .}}{{end}} +{{define "title"}} +{{- if .Preview -}} + {{template "previewing hypha" .HyphaName}} +{{- else -}} + {{template "editing hypha" .HyphaName}} +{{- end -}} +{{end}} +{{define "body"}} +
+
+

+ {{block "editing [[hypha]]" .HyphaName}} + Edit {{beautifulName .}} + {{end}} +

+ {{if .IsNew}} +

+ {{block "you're creating a new hypha" .}}You are creating a new hypha.{{end}} +

+ {{end}} + +

+ +

+

+ + + + {{template "cancel" .}} + +

+
+ {{if .Preview}} +

+ {{block "preview tip" .}}Note that the hypha hasn't been saved yet. Here's the preview:{{end}} +

+
+ {{.Preview}} +
+ {{end}} +
+{{template "toolbar" .}} + +{{range .EditScripts}} + +{{end}} +{{end}} diff --git a/static/default.css b/static/default.css index 663ca91..548b76f 100644 --- a/static/default.css +++ b/static/default.css @@ -99,7 +99,7 @@ textarea {font-size:16px; font-family: inherit; line-height: 150%; } .edit-form p { margin: .25rem 0; } .edit-form__message { width: 100%; margin: 0.25em 0; } .edit-form__save { font-weight: bold; } -.edit-toolbar__buttons, .edit-toolbar__ad { margin: .5rem; } +.edit-toolbar__buttons, .edit-toolbar__help { margin: .5rem; } .edit-form { height: 100%; display: flex; flex-direction: column; } .icon {margin-right: .25rem; vertical-align: bottom; } diff --git a/viewutil/viewutil.go b/viewutil/viewutil.go index 3f61e50..ce29d7c 100644 --- a/viewutil/viewutil.go +++ b/viewutil/viewutil.go @@ -4,12 +4,13 @@ package viewutil import ( "embed" "fmt" - "github.com/bouncepaw/mycorrhiza/cfg" - "github.com/bouncepaw/mycorrhiza/util" "io/fs" "log" "strings" "text/template" // TODO: save the world + + "github.com/bouncepaw/mycorrhiza/cfg" + "github.com/bouncepaw/mycorrhiza/util" ) var ( @@ -95,6 +96,7 @@ type BaseData struct { HeadElements []string HeaderLinks []HeaderLink CommonScripts []string + EditScripts []string Addr string Title string // TODO: remove Body string // TODO: remove @@ -119,6 +121,7 @@ func Base(meta Meta, title, body string, bodyAttributes map[string]string, headE HeadElements: headElements, HeaderLinks: HeaderLinks, CommonScripts: cfg.CommonScripts, + EditScripts: cfg.EditScripts, Body: body, BodyAttributes: bodyAttributes, }) diff --git a/web/mutators.go b/web/mutators.go index e018891..89dac0c 100644 --- a/web/mutators.go +++ b/web/mutators.go @@ -2,12 +2,15 @@ package web import ( "fmt" + "html/template" + "log" + "net/http" + "github.com/bouncepaw/mycomarkup/v5" + "github.com/bouncepaw/mycorrhiza/hypview" "github.com/bouncepaw/mycorrhiza/mycoopts" "github.com/bouncepaw/mycorrhiza/viewutil" - "log" - "net/http" "github.com/bouncepaw/mycomarkup/v5/mycocontext" @@ -148,80 +151,65 @@ func handlerRename(w http.ResponseWriter, rq *http.Request) { func handlerEdit(w http.ResponseWriter, rq *http.Request) { util.PrepareRq(rq) var ( - hyphaName = util.HyphaNameFromRq(rq, "edit") - h = hyphae.ByName(hyphaName) - warning string - textAreaFill string - err error - u = user.FromRequest(rq) - lc = l18n.FromRequest(rq) - meta = viewutil.MetaFrom(w, rq) + u = user.FromRequest(rq) + lc = l18n.FromRequest(rq) + meta = viewutil.MetaFrom(w, rq) + + hyphaName = util.HyphaNameFromRq(rq, "edit") + h = hyphae.ByName(hyphaName) + + isNew bool + content string + err error ) + if err := shroom.CanEdit(u, h, lc); err != nil { viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, err.Error()) return } + switch h.(type) { case *hyphae.EmptyHypha: - warning = fmt.Sprintf(`

%s

`, lc.Get("edit.new_hypha")) + isNew = true default: - textAreaFill, err = hyphae.FetchMycomarkupFile(h) + content, err = hyphae.FetchMycomarkupFile(h) if err != nil { log.Println(err) viewutil.HttpErr(meta, http.StatusInternalServerError, hyphaName, lc.Get("ui.error_text_fetch")) return } } - util.HTTP200Page( - w, - viewutil.Base( - meta, - fmt.Sprintf(lc.Get("edit.title"), util.BeautifulName(hyphaName)), - hypview.Editor(rq, hyphaName, textAreaFill, warning), - map[string]string{})) + hypview.EditHypha(meta, hyphaName, isNew, content, "", "") } // handlerUploadText uploads a new text part for the hypha. func handlerUploadText(w http.ResponseWriter, rq *http.Request) { util.PrepareRq(rq) var ( + u = user.FromRequest(rq) + meta = viewutil.MetaFrom(w, rq) + hyphaName = util.HyphaNameFromRq(rq, "upload-text") h = hyphae.ByName(hyphaName) - textData = rq.PostFormValue("text") - action = rq.PostFormValue("action") - message = rq.PostFormValue("message") - u = user.FromRequest(rq) - lc = l18n.FromRequest(rq) - meta = viewutil.MetaFrom(w, rq) + _, isNew = h.(*hyphae.EmptyHypha) + + textData = rq.PostFormValue("text") + action = rq.PostFormValue("action") + message = rq.PostFormValue("message") ) - if action != "Preview" { - if err := shroom.UploadText(h, []byte(textData), message, u); err != nil { - viewutil.HttpErr(meta, http.StatusForbidden, hyphaName, err.Error()) - return - } - } - - if action == "Preview" { + if action == "preview" { ctx, _ := mycocontext.ContextFromStringInput(textData, mycoopts.MarkupOptions(hyphaName)) - - util.HTTP200Page( - w, - viewutil.Base( - meta, - fmt.Sprintf(lc.Get("edit.preview_title"), util.BeautifulName(hyphaName)), - hypview.Preview( - rq, - hyphaName, - textData, - message, - "", - mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx))), - map[string]string{}, - )) - } else { - http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther) + preview := template.HTML(mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx))) + hypview.EditHypha(meta, hyphaName, isNew, textData, message, preview) + return } + + if err := shroom.UploadText(h, []byte(textData), message, u); err != nil { + viewutil.HttpErr(meta, http.StatusForbidden, hyphaName, err.Error()) + return + } + http.Redirect(w, rq, "/hypha/"+hyphaName, http.StatusSeeOther) } // handlerUploadBinary uploads a new media for the hypha.