~bouncepaw/mycorrhiza-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
4 2

[PATCH 1/2] Fix CommonScripts handling

Details
Message ID
<20220819163332.94100-1-umar@handlerug.me>
DKIM signature
missing
Download raw message
Patch: +3 -1
---
 viewutil/base.html | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/viewutil/base.html b/viewutil/base.html
index b9ccfed..c3a6213 100644
--- a/viewutil/base.html
+++ b/viewutil/base.html
@@ -57,8 +57,10 @@
		<div class="dialog__content"></div>
	</div>
</template>
{{range .CommonScripts}}{{.}}{{end}}
<script src="/static/view.js"></script>
{{range .CommonScripts}}
	<script src="{{.}}"></script>
{{end}}
</body>
</html>
{{end}}
-- 
2.32.1 (Apple Git-133)

[PATCH 2/2] Migrate /edit to html/template

Details
Message ID
<20220819163332.94100-2-umar@handlerug.me>
In-Reply-To
<20220819163332.94100-1-umar@handlerug.me> (view parent)
DKIM signature
missing
Download raw message
Patch: +209 -629
---
This is a fairly large patch so please review carefully

 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          |  86 ++++----
 7 files changed, 209 insertions(+), 629 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..c0bac7a 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]]"}}Редактирование <a href="/hypha/{{.}}">{{beautifulName .}}</a>{{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"}}<a href="/help/en/mycomarkup" class="shy-link">Подробнее</a> о микоразметке{{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
@@ -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) %}
<aside class="edit-toolbar markup-toolbar layout-card">
	<h2 class="edit-toolbar__title layout-card__title">{%s lc.Get("edit.markup")%}</h2>
	<section class="edit-toolbar__buttons">
	{% for _, el := range []struct{
			class string
			display string
		}{
			{"link", fmt.Sprintf("[[%s]]", lc.Get("edit.link"))},
			{"titlelink", fmt.Sprintf("[[%s | %s]]", lc.Get("edit.link"), lc.Get("edit.link_title"))},
			{"heading1", fmt.Sprintf("= %s", lc.Get("edit.heading"))},
			{"heading2", fmt.Sprintf("== %s", lc.Get("edit.heading"))},
			{"bold", fmt.Sprintf("<b>**%s**</b>", lc.Get("edit.bold"))},
			{"italic", fmt.Sprintf("<i>//%s//</i>", lc.Get("edit.italic"))},
			{"highlighted", fmt.Sprintf("<mark>++%s++</mark>", lc.Get("edit.highlight"))},
			{"underline", fmt.Sprintf("<u>__%s__</u>", lc.Get("edit.underline"))},
			{"monospace", fmt.Sprintf("<code>`%s`</code>", lc.Get("edit.mono"))},
			{"lifted", fmt.Sprintf("<sup>^^%s^^</sup>", lc.Get("edit.super"))}, // inconsistent names: lifted, supertext. How cute ❤️
			{"lowered", fmt.Sprintf("<sub>,,%s,,</sub>", lc.Get("edit.sub"))},
			{"strikethrough", fmt.Sprintf("<strike>~~%s~~</strike>", lc.Get("edit.strike"))},
			{"rocket", "=> " + lc.Get("edit.rocket")},
			{"xcl", "<= " + lc.Get("edit.transclude")},
			{"img", "<code>img {}</code>"},
			{"table", "<code>table {}</code>"},
			{"hr", lc.Get("edit.hr")},
			{"codeblock", lc.Get("edit.code")},
			{"bulletedlist", "* " + lc.Get("edit.bullets")},
			{"numberedlist", "*. " + lc.Get("edit.numbers")},
		} %}
		<button class="btn edit-toolbar__btn edit-toolbar__{%s el.class %}">
			{%s= el.display %}
		</button>
	{% endfor %}
	</section>
	<p class="edit-toolbar__ad">{%s= lc.Get("edit.help", &l18n.Replacements{"link": fmt.Sprintf("<a href=\"/help/en/mycomarkup\" target=\"_blank\" class=\"shy-link\">%s</a>", lc.Get("edit.help_link"))}) %}</p>
</aside>
<aside class="edit-toolbar action-toolbar layout-card">
	<h2 class="edit-toolbar__title layout-card__title">{%s lc.Get("edit.actions")%}</h2>
	<section class="edit-toolbar__buttons">
	{% for _, el := range []struct{
			class string
			display string
		}{
			{"date", lc.Get("edit.date")},
			{"time", lc.Get("edit.time")},
		} %}
		<button class="btn edit-toolbar__btn edit-toolbar__{%s el.class %}">
			{%s= el.display %}
		</button>
	{% endfor %}
	{% if u.Group != "anon" %}
		<button class="btn edit-toolbar__btn edit-toolbar__user-link">
			{%s lc.Get("edit.selflink") %}
		</button>
	{% endif %}
	</section>
</aside>
<script src="/static/toolbar.js"></script>
{% endfunc %}

{% func Editor(rq *http.Request, hyphaName, textAreaFill, warning string) %}
{% code
	lc := l18n.FromRequest(rq)
%}
<main class="main-width edit edit_no-preview">
	<form method="post" class="edit-form"
			action="/upload-text/{%s hyphaName %}">
		<h1 class="edit__title">{%s= fmt.Sprintf(lc.Get("edit.title"), beautifulLink(hyphaName)) %}</h1>
		{%s= warning %}
		<textarea name="text" class="edit-form__textarea" autofocus>{%s textAreaFill %}</textarea>
		<p class="edit-form__message-zone">
			<input id="text" type="text" name="message" class="edit-form__message" placeholder="{%s lc.Get("edit.tag") %}" aria-label="{%s lc.Get("edit.tag") %}">
		</p>
		<p class="edit-form__buttons">
			<button type="submit" name="action" class="btn btn_accent edit-form__save" value="Save">{%s lc.Get("edit.save") %}</button>
			<button type="submit" name="action" class="btn edit-form__preview" value="Preview">{%s lc.Get("edit.preview") %}</button>
			<a href="/hypha/{%s hyphaName %}" class="btn btn_weak">{%s lc.Get("ui.cancel") %}</a>
		</p>
	</form>
</main>
{%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)
%}
<main class="main-width edit edit_with-preview">
	<form method="post" class="edit-form"
			action="/upload-text/{%s hyphaName %}">
		<h1 class="edit__title">{%s= fmt.Sprintf(lc.Get("edit.title"), beautifulLink(hyphaName)) %}</h1>
		{%s= warning %}
		<textarea name="text" class="edit-form__textarea" autofocus>{%s textAreaFill %}</textarea>
		<p class="edit-form__message-zone">
        	<input id="text" type="text" name="message" class="edit-form__message" placeholder="{%s lc.Get("edit.tag") %}" aria-label="{%s lc.Get("edit.tag") %}">
        </p>
		<p class="edit-form__buttons">
            <button type="submit" name="action" class="btn btn_accent edit-form__save" value="Save">{%s lc.Get("edit.save") %}</button>
            <button type="submit" name="action" class="btn edit-form__preview" value="Preview">{%s lc.Get("edit.preview") %}</button>
            <a href="/hypha/{%s hyphaName %}" class="btn btn_weak">{%s lc.Get("ui.cancel") %}</a>
        </p>
	</form>
	<p class="warning">{%s lc.Get("edit.preview_tip") %}</p>
	<article class="edit__preview">{%s= renderedPage %}</article>
</main>
{%s= Toolbar(user.FromRequest(rq), lc) %}
{%= editScripts() %}
{% endfunc %}

{% func editScripts() %}
<script src="/static/editor.js"></script>
{% for _, scriptPath := range cfg.EditScripts %}
<script src="{%s scriptPath %}"></script>
{% 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
@@ -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(`
<aside class="edit-toolbar markup-toolbar layout-card">
	<h2 class="edit-toolbar__title layout-card__title">`)
//line hypview/mutators.qtpl:10
	qw422016.E().S(lc.Get("edit.markup"))
//line hypview/mutators.qtpl:10
	qw422016.N().S(`</h2>
	<section class="edit-toolbar__buttons">
	`)
//line hypview/mutators.qtpl:12
	for _, el := range []struct {
		class   string
		display string
	}{
		{"link", fmt.Sprintf("[[%s]]", lc.Get("edit.link"))},
		{"titlelink", fmt.Sprintf("[[%s | %s]]", lc.Get("edit.link"), lc.Get("edit.link_title"))},
		{"heading1", fmt.Sprintf("= %s", lc.Get("edit.heading"))},
		{"heading2", fmt.Sprintf("== %s", lc.Get("edit.heading"))},
		{"bold", fmt.Sprintf("<b>**%s**</b>", lc.Get("edit.bold"))},
		{"italic", fmt.Sprintf("<i>//%s//</i>", lc.Get("edit.italic"))},
		{"highlighted", fmt.Sprintf("<mark>++%s++</mark>", lc.Get("edit.highlight"))},
		{"underline", fmt.Sprintf("<u>__%s__</u>", lc.Get("edit.underline"))},
		{"monospace", fmt.Sprintf("<code>`%s`</code>", lc.Get("edit.mono"))},
		{"lifted", fmt.Sprintf("<sup>^^%s^^</sup>", lc.Get("edit.super"))}, // inconsistent names: lifted, supertext. How cute ❤️
		{"lowered", fmt.Sprintf("<sub>,,%s,,</sub>", lc.Get("edit.sub"))},
		{"strikethrough", fmt.Sprintf("<strike>~~%s~~</strike>", lc.Get("edit.strike"))},
		{"rocket", "=> " + lc.Get("edit.rocket")},
		{"xcl", "<= " + lc.Get("edit.transclude")},
		{"img", "<code>img {}</code>"},
		{"table", "<code>table {}</code>"},
		{"hr", lc.Get("edit.hr")},
		{"codeblock", lc.Get("edit.code")},
		{"bulletedlist", "* " + lc.Get("edit.bullets")},
		{"numberedlist", "*. " + lc.Get("edit.numbers")},
	} {
//line hypview/mutators.qtpl:36
		qw422016.N().S(`
		<button class="btn edit-toolbar__btn edit-toolbar__`)
//line hypview/mutators.qtpl:37
		qw422016.E().S(el.class)
//line hypview/mutators.qtpl:37
		qw422016.N().S(`">
			`)
//line hypview/mutators.qtpl:38
		qw422016.N().S(el.display)
//line hypview/mutators.qtpl:38
		qw422016.N().S(`
		</button>
	`)
//line hypview/mutators.qtpl:40
	}
//line hypview/mutators.qtpl:40
	qw422016.N().S(`
	</section>
	<p class="edit-toolbar__ad">`)
//line hypview/mutators.qtpl:42
	qw422016.N().S(lc.Get("edit.help", &l18n.Replacements{"link": fmt.Sprintf("<a href=\"/help/en/mycomarkup\" target=\"_blank\" class=\"shy-link\">%s</a>", lc.Get("edit.help_link"))}))
//line hypview/mutators.qtpl:42
	qw422016.N().S(`</p>
</aside>
<aside class="edit-toolbar action-toolbar layout-card">
	<h2 class="edit-toolbar__title layout-card__title">`)
//line hypview/mutators.qtpl:45
	qw422016.E().S(lc.Get("edit.actions"))
//line hypview/mutators.qtpl:45
	qw422016.N().S(`</h2>
	<section class="edit-toolbar__buttons">
	`)
//line hypview/mutators.qtpl:47
	for _, el := range []struct {
		class   string
		display string
	}{
		{"date", lc.Get("edit.date")},
		{"time", lc.Get("edit.time")},
	} {
//line hypview/mutators.qtpl:53
		qw422016.N().S(`
		<button class="btn edit-toolbar__btn edit-toolbar__`)
//line hypview/mutators.qtpl:54
		qw422016.E().S(el.class)
//line hypview/mutators.qtpl:54
		qw422016.N().S(`">
			`)
//line hypview/mutators.qtpl:55
		qw422016.N().S(el.display)
//line hypview/mutators.qtpl:55
		qw422016.N().S(`
		</button>
	`)
//line hypview/mutators.qtpl:57
	}
//line hypview/mutators.qtpl:57
	qw422016.N().S(`
	`)
//line hypview/mutators.qtpl:58
	if u.Group != "anon" {
//line hypview/mutators.qtpl:58
		qw422016.N().S(`
		<button class="btn edit-toolbar__btn edit-toolbar__user-link">
			`)
//line hypview/mutators.qtpl:60
		qw422016.E().S(lc.Get("edit.selflink"))
//line hypview/mutators.qtpl:60
		qw422016.N().S(`
		</button>
	`)
//line hypview/mutators.qtpl:62
	}
//line hypview/mutators.qtpl:62
	qw422016.N().S(`
	</section>
</aside>
<script src="/static/toolbar.js"></script>
`)
//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(`
<main class="main-width edit edit_no-preview">
	<form method="post" class="edit-form"
			action="/upload-text/`)
//line hypview/mutators.qtpl:74
	qw422016.E().S(hyphaName)
//line hypview/mutators.qtpl:74
	qw422016.N().S(`">
		<h1 class="edit__title">`)
//line hypview/mutators.qtpl:75
	qw422016.N().S(fmt.Sprintf(lc.Get("edit.title"), beautifulLink(hyphaName)))
//line hypview/mutators.qtpl:75
	qw422016.N().S(`</h1>
		`)
//line hypview/mutators.qtpl:76
	qw422016.N().S(warning)
//line hypview/mutators.qtpl:76
	qw422016.N().S(`
		<textarea name="text" class="edit-form__textarea" autofocus>`)
//line hypview/mutators.qtpl:77
	qw422016.E().S(textAreaFill)
//line hypview/mutators.qtpl:77
	qw422016.N().S(`</textarea>
		<p class="edit-form__message-zone">
			<input id="text" type="text" name="message" class="edit-form__message" placeholder="`)
//line hypview/mutators.qtpl:79
	qw422016.E().S(lc.Get("edit.tag"))
//line hypview/mutators.qtpl:79
	qw422016.N().S(`" aria-label="`)
//line hypview/mutators.qtpl:79
	qw422016.E().S(lc.Get("edit.tag"))
//line hypview/mutators.qtpl:79
	qw422016.N().S(`">
		</p>
		<p class="edit-form__buttons">
			<button type="submit" name="action" class="btn btn_accent edit-form__save" value="Save">`)
//line hypview/mutators.qtpl:82
	qw422016.E().S(lc.Get("edit.save"))
//line hypview/mutators.qtpl:82
	qw422016.N().S(`</button>
			<button type="submit" name="action" class="btn edit-form__preview" value="Preview">`)
//line hypview/mutators.qtpl:83
	qw422016.E().S(lc.Get("edit.preview"))
//line hypview/mutators.qtpl:83
	qw422016.N().S(`</button>
			<a href="/hypha/`)
//line hypview/mutators.qtpl:84
	qw422016.E().S(hyphaName)
//line hypview/mutators.qtpl:84
	qw422016.N().S(`" class="btn btn_weak">`)
//line hypview/mutators.qtpl:84
	qw422016.E().S(lc.Get("ui.cancel"))
//line hypview/mutators.qtpl:84
	qw422016.N().S(`</a>
		</p>
	</form>
</main>
`)
//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(`
<main class="main-width edit edit_with-preview">
	<form method="post" class="edit-form"
			action="/upload-text/`)
//line hypview/mutators.qtpl:98
	qw422016.E().S(hyphaName)
//line hypview/mutators.qtpl:98
	qw422016.N().S(`">
		<h1 class="edit__title">`)
//line hypview/mutators.qtpl:99
	qw422016.N().S(fmt.Sprintf(lc.Get("edit.title"), beautifulLink(hyphaName)))
//line hypview/mutators.qtpl:99
	qw422016.N().S(`</h1>
		`)
//line hypview/mutators.qtpl:100
	qw422016.N().S(warning)
//line hypview/mutators.qtpl:100
	qw422016.N().S(`
		<textarea name="text" class="edit-form__textarea" autofocus>`)
//line hypview/mutators.qtpl:101
	qw422016.E().S(textAreaFill)
//line hypview/mutators.qtpl:101
	qw422016.N().S(`</textarea>
		<p class="edit-form__message-zone">
        	<input id="text" type="text" name="message" class="edit-form__message" placeholder="`)
//line hypview/mutators.qtpl:103
	qw422016.E().S(lc.Get("edit.tag"))
//line hypview/mutators.qtpl:103
	qw422016.N().S(`" aria-label="`)
//line hypview/mutators.qtpl:103
	qw422016.E().S(lc.Get("edit.tag"))
//line hypview/mutators.qtpl:103
	qw422016.N().S(`">
        </p>
		<p class="edit-form__buttons">
            <button type="submit" name="action" class="btn btn_accent edit-form__save" value="Save">`)
//line hypview/mutators.qtpl:106
	qw422016.E().S(lc.Get("edit.save"))
//line hypview/mutators.qtpl:106
	qw422016.N().S(`</button>
            <button type="submit" name="action" class="btn edit-form__preview" value="Preview">`)
//line hypview/mutators.qtpl:107
	qw422016.E().S(lc.Get("edit.preview"))
//line hypview/mutators.qtpl:107
	qw422016.N().S(`</button>
            <a href="/hypha/`)
//line hypview/mutators.qtpl:108
	qw422016.E().S(hyphaName)
//line hypview/mutators.qtpl:108
	qw422016.N().S(`" class="btn btn_weak">`)
//line hypview/mutators.qtpl:108
	qw422016.E().S(lc.Get("ui.cancel"))
//line hypview/mutators.qtpl:108
	qw422016.N().S(`</a>
        </p>
	</form>
	<p class="warning">`)
//line hypview/mutators.qtpl:111
	qw422016.E().S(lc.Get("edit.preview_tip"))
//line hypview/mutators.qtpl:111
	qw422016.N().S(`</p>
	<article class="edit__preview">`)
//line hypview/mutators.qtpl:112
	qw422016.N().S(renderedPage)
//line hypview/mutators.qtpl:112
	qw422016.N().S(`</article>
</main>
`)
//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(`
<script src="/static/editor.js"></script>
`)
//line hypview/mutators.qtpl:120
	for _, scriptPath := range cfg.EditScripts {
//line hypview/mutators.qtpl:120
		qw422016.N().S(`
<script src="`)
//line hypview/mutators.qtpl:121
		qw422016.E().S(scriptPath)
//line hypview/mutators.qtpl:121
		qw422016.N().S(`"></script>
`)
//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"}}
<aside class="edit-toolbar markup-toolbar layout-card">
    <h2 class="edit-toolbar__title layout-card__title">{{block "markup" .}}Markup{{end}}</h2>
    <section class="edit-toolbar__buttons">
        <button class="btn edit-toolbar__btn edit-toolbar__link">[[{{block "link" .}}Link{{end}}]]</button>
        <button class="btn edit-toolbar__btn edit-toolbar__titlelink">[[{{template "link" .}} | {{block "link title" .}}Title{{end}}]]</button>
        <button class="btn edit-toolbar__btn edit-toolbar__heading1">= {{block "heading" .}}Heading{{end}}</button>
        <button class="btn edit-toolbar__btn edit-toolbar__heading2">== {{template "heading" .}}</button>
        <button class="btn edit-toolbar__btn edit-toolbar__bold"><b>**{{block "bold" .}}Bold{{end}}**</b></button>
        <button class="btn edit-toolbar__btn edit-toolbar__italic"><i>//{{block "italic" .}}Italic{{end}}//</i></button>
        <button class="btn edit-toolbar__btn edit-toolbar__highlighted"><mark>++{{block "highlight" .}}Highlight{{end}}++</mark></button>
        <button class="btn edit-toolbar__btn edit-toolbar__underline"><u>__{{block "underline" .}}Underline{{end}}__</u></button>
        <button class="btn edit-toolbar__btn edit-toolbar__monospace"><code>`{{block "mono" .}}Monospace{{end}}`</code></button>
        <button class="btn edit-toolbar__btn edit-toolbar__lifted"><sup>^^{{block "super" .}}Supertext{{end}}^^</sup></button>
        <button class="btn edit-toolbar__btn edit-toolbar__lowered"><sub>,,{{block "sub" .}}Subtext{{end}},,</sub></button>
        <button class="btn edit-toolbar__btn edit-toolbar__strikethrough"><s>~~{{block "strike" .}}Strikethrough{{end}}~~</s></button>
        <button class="btn edit-toolbar__btn edit-toolbar__rocket">=> {{block "rocket" .}}Rocketlink{{end}}</button>
        <button class="btn edit-toolbar__btn edit-toolbar__xcl"><= {{block "transclude" .}}Transclusion{{end}}</button>
        <button class="btn edit-toolbar__btn edit-toolbar__img"><code>img {}</code></button>
        <button class="btn edit-toolbar__btn edit-toolbar__table"><code>table {}</code></button>
        <button class="btn edit-toolbar__btn edit-toolbar__hr">{{block "hr" .}}Horizontal bar{{end}}</button>
        <button class="btn edit-toolbar__btn edit-toolbar__codeblock">{{block "code" .}}Code block{{end}}</button>
        <button class="btn edit-toolbar__btn edit-toolbar__bulletedlist">* {{block "bullets" .}}Bullet list{{end}}</button>
        <button class="btn edit-toolbar__btn edit-toolbar__numberedlist">*. {{block "numbers" .}}Number list{{end}}</button>
    </section>
    <p class="edit-toolbar__help">
        {{block "mycomarkup help" .}}
            <a href="/help/en/mycomarkup" target="_blank" class="shy-link">Learn more</a> about mycomarkup
        {{end}}
    </p>
</aside>
<aside class="edit-toolbar action-toolbar layout-card">
    <h2 class="edit-toolbar__title layout-card__title">{{block "actions" .}}Actions{{end}}</h2>
    <section class="edit-toolbar__buttons">
        <button class="btn edit-toolbar__btn edit-toolbar__date">{{block "current date" .}}Insert current date{{end}}</button>
        <button class="btn edit-toolbar__btn edit-toolbar__time">{{block "current time" .}}Insert current time{{end}}</button>
        {{if .Meta.U.Group | ne "anon"}}
        <button class="btn edit-toolbar__btn edit-toolbar__user-link">{{block "selflink" .}}Link yourself{{end}}</button>
        {{end}}
    </section>
</aside>
<script src="/static/toolbar.js"></script>
{{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"}}
<main class="main-width edit {{if .Preview}}edit_with-preview{{else}}edit_no-preview{{end}}">
    <form method="post" class="edit-form" action="/upload-text/{{.HyphaName}}">
        <h1 class="edit__title">
            {{block "editing [[hypha]]" .HyphaName}}
                Edit <a href="/hypha/{{.}}">{{beautifulName .}}</a>
            {{end}}
        </h1>
        {{if .IsNew}}
            <p class="warning warning_new-hypha">
                {{block "you're creating a new hypha" .}}You are creating a new hypha.{{end}}
            </p>
        {{end}}
        <textarea name="text" class="edit-form__textarea" autofocus>{{.Content}}</textarea>
        <p class="edit-form__message-zone">
            <input
                id="text"
                type="text"
                name="message"
                class="edit-form__message"
                value="{{.Message}}"
                placeholder="{{block "describe your changes" .}}Describe your changes{{end}}"
                aria-label="{{template "describe your changes" .}}">
        </p>
        <p class="edit-form__buttons">
            <button type="submit" name="action" class="btn btn_accent edit-form__save" value="save">
                {{template "save" .}}
            </button>
            <button type="submit" name="action" class="btn edit-form__preview" value="preview">
                {{block "preview" .}}Preview{{end}}
            </button>
            <a href="/hypha/{{.HyphaName}}" class="btn btn_weak">
                {{template "cancel" .}}
            </a>
        </p>
    </form>
    {{if .Preview}}
        <p class="warning">
            {{block "preview tip" .}}Note that the hypha hasn't been saved yet. Here's the preview:{{end}}
        </p>
        <article class="edit__preview">
            {{.Preview}}
        </article>
    {{end}}
</main>
{{template "toolbar" .}}
<script src="/static/editor.js"></script>
{{range .EditScripts}}
    <script src="{{.}}"></script>
{{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(`<p class="warning warning_new-hypha">%s</p>`, 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)

	if action != "Preview" {
		if err := shroom.UploadText(h, []byte(textData), message, u); err != nil {
			viewutil.HttpErr(meta, http.StatusForbidden, hyphaName, err.Error())
			return
		}
	}
		textData = rq.PostFormValue("text")
		action   = rq.PostFormValue("action")
		message  = rq.PostFormValue("message")
	)

	if action == "Preview" {
	if action == "preview" {
		ctx, _ := mycocontext.ContextFromStringInput(textData, mycoopts.MarkupOptions(hyphaName))
		preview := template.HTML(mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx)))
		hypview.EditHypha(meta, hyphaName, isNew, textData, message, preview)
		return
	}

		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)
	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.
-- 
2.32.1 (Apple Git-133)
Details
Message ID
<0564c008-9388-8f7f-fdfb-797bdb98a161@ya.ru>
In-Reply-To
<20220819163332.94100-1-umar@handlerug.me> (view parent)
DKIM signature
missing
Download raw message
Thanks! Merged the first patch.

Re: [PATCH 2/2] Migrate /edit to html/template

Details
Message ID
<758f5885-7cbe-0ec4-454b-6b1b289142ea@ya.ru>
In-Reply-To
<20220819163332.94100-2-umar@handlerug.me> (view parent)
DKIM signature
missing
Download raw message
> +{{define "you're creating a new hypha'"}}Вы создаёте новую гифу.{{end}}

This one does not get applied. Beware of the extra '.

> +<aside class="edit-toolbar markup-toolbar layout-card">
> +    <h2 class="edit-toolbar__title layout-card__title">{{block "markup" .}}Markup{{end}}</h2>
> +    <section class="edit-toolbar__buttons">
> +        <button class="btn edit-toolbar__btn edit-toolbar__link">[[{{block "link" .}}Link{{end}}]]</button>
> +        <button class="btn edit-toolbar__btn edit-toolbar__titlelink">[[{{template "link" .}} | {{block "link title" .}}Title{{end}}]]</button>

You should probably wrap it in some loop and call a separate template for <button>. Or write out many calls of the same template.

Re: [PATCH 2/2] Migrate /edit to html/template

Details
Message ID
<CMA6UYIJZNTC.1TIS97FG8TV1C@venus.local>
In-Reply-To
<758f5885-7cbe-0ec4-454b-6b1b289142ea@ya.ru> (view parent)
DKIM signature
missing
Download raw message
On Fri Aug 19, 2022 at 8:40 PM +03, Timur Ismagilov wrote:
> > +{{define "you're creating a new hypha'"}}Вы создаёте новую гифу.{{end}}
>
> This one does not get applied. Beware of the extra '.

Indeed, you're right. I'll fix that in v2.

> > +<aside class="edit-toolbar markup-toolbar layout-card">
> > +    <h2 class="edit-toolbar__title layout-card__title">{{block "markup" .}}Markup{{end}}</h2>
> > +    <section class="edit-toolbar__buttons">
> > +        <button class="btn edit-toolbar__btn edit-toolbar__link">[[{{block "link" .}}Link{{end}}]]</button>
> > +        <button class="btn edit-toolbar__btn edit-toolbar__titlelink">[[{{template "link" .}} | {{block "link title" .}}Title{{end}}]]</button>
>
> You should probably wrap it in some loop and call a separate template for <button>. Or write out many calls of the same template.

Oh, I did not think of templates. I'll refactor this piece of code in v2
as well, thanks for feedback.
Reply to thread Export thread (mbox)