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= 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 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: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: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"}}
+
+
+ {{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.