Megarefactoring of hypha views
This commit is contained in:
parent
68a7573764
commit
ea1ae0d078
@ -2,12 +2,13 @@ package hypview
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
"github.com/bouncepaw/mycorrhiza/internal/backlinks"
|
|
||||||
"github.com/bouncepaw/mycorrhiza/internal/cfg"
|
|
||||||
"github.com/bouncepaw/mycorrhiza/web/viewutil"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/bouncepaw/mycorrhiza/internal/backlinks"
|
||||||
|
"github.com/bouncepaw/mycorrhiza/internal/cfg"
|
||||||
|
"github.com/bouncepaw/mycorrhiza/web/viewutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@ -1,50 +0,0 @@
|
|||||||
{% import "github.com/bouncepaw/mycorrhiza/internal/backlinks" %}
|
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/internal/cfg" %}
|
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/internal/hyphae" %}
|
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/internal/user" %}
|
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/util" %}
|
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/web/viewutil" %}
|
|
||||||
|
|
||||||
{% func hyphaInfoEntry(h hyphae.Hypha, u *user.User, action string, hasToExist bool, displayText string) %}
|
|
||||||
{% code flag := true %}
|
|
||||||
{% switch h.(type) %}
|
|
||||||
{% case *hyphae.EmptyHypha %}
|
|
||||||
{% code flag = !hasToExist %}
|
|
||||||
{% endswitch %}
|
|
||||||
{% if u.CanProceed(action) && flag %}
|
|
||||||
<li class="hypha-info__entry hypha-info__entry_{%s action %}">
|
|
||||||
<a class="hypha-info__link" href="/{%s action %}/{%s h.CanonicalName() %}">{%s displayText %}</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% endfunc %}
|
|
||||||
|
|
||||||
{% func hyphaInfo(meta viewutil.Meta, h hyphae.Hypha) %}
|
|
||||||
{% code
|
|
||||||
u := meta.U
|
|
||||||
lc := meta.Lc
|
|
||||||
backs := backlinks.BacklinksCount(h.CanonicalName())
|
|
||||||
%}
|
|
||||||
<nav class="hypha-info">
|
|
||||||
<ul class="hypha-info__list">
|
|
||||||
{%= hyphaInfoEntry(h, u, "history", false, lc.Get("ui.history_link")) %}
|
|
||||||
{%= hyphaInfoEntry(h, u, "rename", true, lc.Get("ui.rename_link")) %}
|
|
||||||
{%= hyphaInfoEntry(h, u, "delete", true, lc.Get("ui.delete_link")) %}
|
|
||||||
{%= hyphaInfoEntry(h, u, "text", true, lc.Get("ui.text_link")) %}
|
|
||||||
{% switch h := h.(type) %}
|
|
||||||
{% case *hyphae.TextualHypha %}
|
|
||||||
{%= hyphaInfoEntry(h, u, "media", true, lc.Get("ui.media_link_for_textual")) %}
|
|
||||||
{% default %}
|
|
||||||
{%= hyphaInfoEntry(h, u, "media", true, lc.Get("ui.media_link")) %}
|
|
||||||
{% endswitch %}
|
|
||||||
{%= hyphaInfoEntry(h, u, "backlinks", false, lc.GetPlural("ui.backlinks_link", backs)) %}
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
{% endfunc %}
|
|
||||||
|
|
||||||
{% func commonScripts() %}
|
|
||||||
{% for _, scriptPath := range cfg.CommonScripts %}
|
|
||||||
<script src="{%s scriptPath %}"></script>
|
|
||||||
{% endfor %}
|
|
||||||
{% endfunc %}
|
|
||||||
|
|
||||||
{% func beautifulLink(hyphaName string) %}<a href="/hypha/{%s= hyphaName %}">{%s util.BeautifulName(hyphaName) %}</a>{% endfunc %}
|
|
||||||
@ -1,311 +0,0 @@
|
|||||||
// Code generated by qtc from "nav.qtpl". DO NOT EDIT.
|
|
||||||
// See https://github.com/valyala/quicktemplate for details.
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:1
|
|
||||||
package hypview
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:1
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/internal/backlinks"
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:2
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/internal/cfg"
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:3
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/internal/hyphae"
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:4
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/internal/user"
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:5
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/util"
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:6
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/web/viewutil"
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:8
|
|
||||||
import (
|
|
||||||
qtio422016 "io"
|
|
||||||
|
|
||||||
qt422016 "github.com/valyala/quicktemplate"
|
|
||||||
)
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:8
|
|
||||||
var (
|
|
||||||
_ = qtio422016.Copy
|
|
||||||
_ = qt422016.AcquireByteBuffer
|
|
||||||
)
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:8
|
|
||||||
func streamhyphaInfoEntry(qw422016 *qt422016.Writer, h hyphae.Hypha, u *user.User, action string, hasToExist bool, displayText string) {
|
|
||||||
//line hypview/nav.qtpl:8
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:9
|
|
||||||
flag := true
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:9
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:10
|
|
||||||
switch h.(type) {
|
|
||||||
//line hypview/nav.qtpl:11
|
|
||||||
case *hyphae.EmptyHypha:
|
|
||||||
//line hypview/nav.qtpl:11
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:12
|
|
||||||
flag = !hasToExist
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:12
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:13
|
|
||||||
}
|
|
||||||
//line hypview/nav.qtpl:13
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:14
|
|
||||||
if u.CanProceed(action) && flag {
|
|
||||||
//line hypview/nav.qtpl:14
|
|
||||||
qw422016.N().S(`
|
|
||||||
<li class="hypha-info__entry hypha-info__entry_`)
|
|
||||||
//line hypview/nav.qtpl:15
|
|
||||||
qw422016.E().S(action)
|
|
||||||
//line hypview/nav.qtpl:15
|
|
||||||
qw422016.N().S(`">
|
|
||||||
<a class="hypha-info__link" href="/`)
|
|
||||||
//line hypview/nav.qtpl:16
|
|
||||||
qw422016.E().S(action)
|
|
||||||
//line hypview/nav.qtpl:16
|
|
||||||
qw422016.N().S(`/`)
|
|
||||||
//line hypview/nav.qtpl:16
|
|
||||||
qw422016.E().S(h.CanonicalName())
|
|
||||||
//line hypview/nav.qtpl:16
|
|
||||||
qw422016.N().S(`">`)
|
|
||||||
//line hypview/nav.qtpl:16
|
|
||||||
qw422016.E().S(displayText)
|
|
||||||
//line hypview/nav.qtpl:16
|
|
||||||
qw422016.N().S(`</a>
|
|
||||||
</li>
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:18
|
|
||||||
}
|
|
||||||
//line hypview/nav.qtpl:18
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
func writehyphaInfoEntry(qq422016 qtio422016.Writer, h hyphae.Hypha, u *user.User, action string, hasToExist bool, displayText string) {
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
streamhyphaInfoEntry(qw422016, h, u, action, hasToExist, displayText)
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
qt422016.ReleaseWriter(qw422016)
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
func hyphaInfoEntry(h hyphae.Hypha, u *user.User, action string, hasToExist bool, displayText string) string {
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
writehyphaInfoEntry(qb422016, h, u, action, hasToExist, displayText)
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
qs422016 := string(qb422016.B)
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
return qs422016
|
|
||||||
//line hypview/nav.qtpl:19
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:21
|
|
||||||
func streamhyphaInfo(qw422016 *qt422016.Writer, meta viewutil.Meta, h hyphae.Hypha) {
|
|
||||||
//line hypview/nav.qtpl:21
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:23
|
|
||||||
u := meta.U
|
|
||||||
lc := meta.Lc
|
|
||||||
backs := backlinks.BacklinksCount(h.CanonicalName())
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:26
|
|
||||||
qw422016.N().S(`
|
|
||||||
<nav class="hypha-info">
|
|
||||||
<ul class="hypha-info__list">
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:29
|
|
||||||
streamhyphaInfoEntry(qw422016, h, u, "history", false, lc.Get("ui.history_link"))
|
|
||||||
//line hypview/nav.qtpl:29
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:30
|
|
||||||
streamhyphaInfoEntry(qw422016, h, u, "rename", true, lc.Get("ui.rename_link"))
|
|
||||||
//line hypview/nav.qtpl:30
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:31
|
|
||||||
streamhyphaInfoEntry(qw422016, h, u, "delete", true, lc.Get("ui.delete_link"))
|
|
||||||
//line hypview/nav.qtpl:31
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:32
|
|
||||||
streamhyphaInfoEntry(qw422016, h, u, "text", true, lc.Get("ui.text_link"))
|
|
||||||
//line hypview/nav.qtpl:32
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:33
|
|
||||||
switch h := h.(type) {
|
|
||||||
//line hypview/nav.qtpl:34
|
|
||||||
case *hyphae.TextualHypha:
|
|
||||||
//line hypview/nav.qtpl:34
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:35
|
|
||||||
streamhyphaInfoEntry(qw422016, h, u, "media", true, lc.Get("ui.media_link_for_textual"))
|
|
||||||
//line hypview/nav.qtpl:35
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:36
|
|
||||||
default:
|
|
||||||
//line hypview/nav.qtpl:36
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:37
|
|
||||||
streamhyphaInfoEntry(qw422016, h, u, "media", true, lc.Get("ui.media_link"))
|
|
||||||
//line hypview/nav.qtpl:37
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:38
|
|
||||||
}
|
|
||||||
//line hypview/nav.qtpl:38
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:39
|
|
||||||
streamhyphaInfoEntry(qw422016, h, u, "backlinks", false, lc.GetPlural("ui.backlinks_link", backs))
|
|
||||||
//line hypview/nav.qtpl:39
|
|
||||||
qw422016.N().S(`
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
func writehyphaInfo(qq422016 qtio422016.Writer, meta viewutil.Meta, h hyphae.Hypha) {
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
streamhyphaInfo(qw422016, meta, h)
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
qt422016.ReleaseWriter(qw422016)
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
func hyphaInfo(meta viewutil.Meta, h hyphae.Hypha) string {
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
writehyphaInfo(qb422016, meta, h)
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
qs422016 := string(qb422016.B)
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
return qs422016
|
|
||||||
//line hypview/nav.qtpl:42
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:44
|
|
||||||
func streamcommonScripts(qw422016 *qt422016.Writer) {
|
|
||||||
//line hypview/nav.qtpl:44
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:45
|
|
||||||
for _, scriptPath := range cfg.CommonScripts {
|
|
||||||
//line hypview/nav.qtpl:45
|
|
||||||
qw422016.N().S(`
|
|
||||||
<script src="`)
|
|
||||||
//line hypview/nav.qtpl:46
|
|
||||||
qw422016.E().S(scriptPath)
|
|
||||||
//line hypview/nav.qtpl:46
|
|
||||||
qw422016.N().S(`"></script>
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:47
|
|
||||||
}
|
|
||||||
//line hypview/nav.qtpl:47
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
func writecommonScripts(qq422016 qtio422016.Writer) {
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
streamcommonScripts(qw422016)
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
qt422016.ReleaseWriter(qw422016)
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
func commonScripts() string {
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
writecommonScripts(qb422016)
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
qs422016 := string(qb422016.B)
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
return qs422016
|
|
||||||
//line hypview/nav.qtpl:48
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
func streambeautifulLink(qw422016 *qt422016.Writer, hyphaName string) {
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
qw422016.N().S(`<a href="/hypha/`)
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
qw422016.N().S(hyphaName)
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
qw422016.N().S(`">`)
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
qw422016.E().S(util.BeautifulName(hyphaName))
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
qw422016.N().S(`</a>`)
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
func writebeautifulLink(qq422016 qtio422016.Writer, hyphaName string) {
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
streambeautifulLink(qw422016, hyphaName)
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
qt422016.ReleaseWriter(qw422016)
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
func beautifulLink(hyphaName string) string {
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
writebeautifulLink(qb422016, hyphaName)
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
qs422016 := string(qb422016.B)
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
return qs422016
|
|
||||||
//line hypview/nav.qtpl:50
|
|
||||||
}
|
|
||||||
@ -1,94 +0,0 @@
|
|||||||
{% import "net/http" %}
|
|
||||||
{% import "strings" %}
|
|
||||||
{% import "path" %}
|
|
||||||
{% import "os" %}
|
|
||||||
|
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/internal/cfg" %}
|
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/internal/hyphae" %}
|
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/l18n" %}
|
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/internal/mimetype" %}
|
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/internal/user" %}
|
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/web/viewutil" %}
|
|
||||||
|
|
||||||
{% func MediaMenu(rq *http.Request, h hyphae.Hypha, u *user.User) %}
|
|
||||||
{% code
|
|
||||||
lc := l18n.FromRequest(rq)
|
|
||||||
%}
|
|
||||||
<main class="main-width media-tab">
|
|
||||||
<h1>{%s= lc.Get("ui.media_title", &l18n.Replacements{"name": beautifulLink(h.CanonicalName())}) %}</h1>
|
|
||||||
{% switch h.(type) %}
|
|
||||||
{% case *hyphae.MediaHypha %}
|
|
||||||
<p class="explanation">{%s lc.Get("ui.media_tip") %} <a href="/help/en/media" class="shy-link">{%s lc.Get("ui.media_what_is") %}</a></p>
|
|
||||||
{% default %}
|
|
||||||
<p class="explanation">{%s lc.Get("ui.media_empty") %} <a href="/help/en/media" class="shy-link">{%s lc.Get("ui.media_what_is") %}</a></p>
|
|
||||||
{% endswitch %}
|
|
||||||
|
|
||||||
<section class="amnt-grid">
|
|
||||||
{% switch h := h.(type) %}
|
|
||||||
{% case *hyphae.MediaHypha %}
|
|
||||||
{% code
|
|
||||||
mime := mimetype.FromExtension(path.Ext(h.MediaFilePath()))
|
|
||||||
fileinfo, err := os.Stat(h.MediaFilePath()) %}
|
|
||||||
{% if err == nil %}
|
|
||||||
<fieldset class="amnt-menu-block">
|
|
||||||
<legend class="modal__title modal__title_small">{%s lc.Get("ui.media_stat") %}</legend>
|
|
||||||
<p class="modal__confirmation-msg"><b>{%s lc.Get("ui.media_stat_size") %}</b> {%s lc.GetPlural64("ui.media_size_value", fileinfo.Size())%}</p>
|
|
||||||
<p><b>{%s lc.Get("ui.media_stat_mime") %}</b> {%s mime %}</p>
|
|
||||||
</fieldset>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if strings.HasPrefix(mime, "image/") %}
|
|
||||||
<fieldset class="amnt-menu-block">
|
|
||||||
<legend class="modal__title modal__title_small">{%s lc.Get("ui.media_include") %}</legend>
|
|
||||||
<p class="modal__confirmation-msg">{%s lc.Get("ui.media_include_tip") %}</p>
|
|
||||||
<pre class="codeblock"><code>img { {%s h.CanonicalName() %} }</code></pre>
|
|
||||||
</fieldset>
|
|
||||||
{% endif %}
|
|
||||||
{% endswitch %}
|
|
||||||
|
|
||||||
{% if u.CanProceed("upload-binary") %}
|
|
||||||
<form action="/upload-binary/{%s h.CanonicalName() %}"
|
|
||||||
method="post" enctype="multipart/form-data"
|
|
||||||
class="upload-binary modal amnt-menu-block">
|
|
||||||
<fieldset class="modal__fieldset">
|
|
||||||
<legend class="modal__title modal__title_small">{%s lc.Get("ui.media_new") %}</legend>
|
|
||||||
<p class="modal__confirmation-msg">{%s lc.Get("ui.media_new_tip") %}</p>
|
|
||||||
<label for="upload-binary__input"></label>
|
|
||||||
<input type="file" id="upload-binary__input" name="binary">
|
|
||||||
|
|
||||||
<button type="submit" class="btn stick-to-bottom" value="Upload">{%s lc.Get("ui.media_upload")%}</button>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
|
|
||||||
{% switch h := h.(type) %}
|
|
||||||
{% case *hyphae.MediaHypha %}
|
|
||||||
{% if u.CanProceed("remove-media") %}
|
|
||||||
<form action="/remove-media/{%s h.CanonicalName() %}" method="post" class="modal amnt-menu-block" method="POST">
|
|
||||||
<fieldset class="modal__fieldset">
|
|
||||||
<legend class="modal__title modal__title_small">{%s lc.Get("ui.media_remove") %}</legend>
|
|
||||||
<p class="modal__confirmation-msg">{%s lc.Get("ui.media_remove_tip") %}</p>
|
|
||||||
<button type="submit" class="btn" value="Remove media">{%s lc.Get("ui.media_remove_button") %}</button>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
{% endswitch %}
|
|
||||||
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
{% endfunc %}
|
|
||||||
|
|
||||||
|
|
||||||
{% func Revision(meta viewutil.Meta, h hyphae.Hypha, contents, revHash string) %}
|
|
||||||
<main class="main-width">
|
|
||||||
<section>
|
|
||||||
<p>{%s meta.Lc.Get("ui.revision_warning") %} <a href="/rev-text/{%s revHash %}/{%s h.CanonicalName() %}">{%s meta.Lc.Get("ui.revision_link") %}</a></p>
|
|
||||||
{%s= NaviTitle(meta, h.CanonicalName()) %}
|
|
||||||
{%s= contents %}
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
{% for _, scriptPath := range cfg.ViewScripts %}
|
|
||||||
<script src="{%s scriptPath %}"></script>
|
|
||||||
{% endfor %}
|
|
||||||
{% endfunc %}
|
|
||||||
@ -1,382 +0,0 @@
|
|||||||
// Code generated by qtc from "readers.qtpl". DO NOT EDIT.
|
|
||||||
// See https://github.com/valyala/quicktemplate for details.
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:1
|
|
||||||
package hypview
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:1
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:2
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:3
|
|
||||||
import "path"
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:4
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:6
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/internal/cfg"
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:7
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/internal/hyphae"
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:8
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/l18n"
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:9
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/internal/mimetype"
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:10
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/internal/user"
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:11
|
|
||||||
import "github.com/bouncepaw/mycorrhiza/web/viewutil"
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:13
|
|
||||||
import (
|
|
||||||
qtio422016 "io"
|
|
||||||
|
|
||||||
qt422016 "github.com/valyala/quicktemplate"
|
|
||||||
)
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:13
|
|
||||||
var (
|
|
||||||
_ = qtio422016.Copy
|
|
||||||
_ = qt422016.AcquireByteBuffer
|
|
||||||
)
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:13
|
|
||||||
func StreamMediaMenu(qw422016 *qt422016.Writer, rq *http.Request, h hyphae.Hypha, u *user.User) {
|
|
||||||
//line hypview/readers.qtpl:13
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:15
|
|
||||||
lc := l18n.FromRequest(rq)
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:16
|
|
||||||
qw422016.N().S(`
|
|
||||||
<main class="main-width media-tab">
|
|
||||||
<h1>`)
|
|
||||||
//line hypview/readers.qtpl:18
|
|
||||||
qw422016.N().S(lc.Get("ui.media_title", &l18n.Replacements{"name": beautifulLink(h.CanonicalName())}))
|
|
||||||
//line hypview/readers.qtpl:18
|
|
||||||
qw422016.N().S(`</h1>
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:19
|
|
||||||
switch h.(type) {
|
|
||||||
//line hypview/readers.qtpl:20
|
|
||||||
case *hyphae.MediaHypha:
|
|
||||||
//line hypview/readers.qtpl:20
|
|
||||||
qw422016.N().S(`
|
|
||||||
<p class="explanation">`)
|
|
||||||
//line hypview/readers.qtpl:21
|
|
||||||
qw422016.E().S(lc.Get("ui.media_tip"))
|
|
||||||
//line hypview/readers.qtpl:21
|
|
||||||
qw422016.N().S(` <a href="/help/en/media" class="shy-link">`)
|
|
||||||
//line hypview/readers.qtpl:21
|
|
||||||
qw422016.E().S(lc.Get("ui.media_what_is"))
|
|
||||||
//line hypview/readers.qtpl:21
|
|
||||||
qw422016.N().S(`</a></p>
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:22
|
|
||||||
default:
|
|
||||||
//line hypview/readers.qtpl:22
|
|
||||||
qw422016.N().S(`
|
|
||||||
<p class="explanation">`)
|
|
||||||
//line hypview/readers.qtpl:23
|
|
||||||
qw422016.E().S(lc.Get("ui.media_empty"))
|
|
||||||
//line hypview/readers.qtpl:23
|
|
||||||
qw422016.N().S(` <a href="/help/en/media" class="shy-link">`)
|
|
||||||
//line hypview/readers.qtpl:23
|
|
||||||
qw422016.E().S(lc.Get("ui.media_what_is"))
|
|
||||||
//line hypview/readers.qtpl:23
|
|
||||||
qw422016.N().S(`</a></p>
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:24
|
|
||||||
}
|
|
||||||
//line hypview/readers.qtpl:24
|
|
||||||
qw422016.N().S(`
|
|
||||||
|
|
||||||
<section class="amnt-grid">
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:27
|
|
||||||
switch h := h.(type) {
|
|
||||||
//line hypview/readers.qtpl:28
|
|
||||||
case *hyphae.MediaHypha:
|
|
||||||
//line hypview/readers.qtpl:28
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:30
|
|
||||||
mime := mimetype.FromExtension(path.Ext(h.MediaFilePath()))
|
|
||||||
fileinfo, err := os.Stat(h.MediaFilePath())
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:31
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:32
|
|
||||||
if err == nil {
|
|
||||||
//line hypview/readers.qtpl:32
|
|
||||||
qw422016.N().S(`
|
|
||||||
<fieldset class="amnt-menu-block">
|
|
||||||
<legend class="modal__title modal__title_small">`)
|
|
||||||
//line hypview/readers.qtpl:34
|
|
||||||
qw422016.E().S(lc.Get("ui.media_stat"))
|
|
||||||
//line hypview/readers.qtpl:34
|
|
||||||
qw422016.N().S(`</legend>
|
|
||||||
<p class="modal__confirmation-msg"><b>`)
|
|
||||||
//line hypview/readers.qtpl:35
|
|
||||||
qw422016.E().S(lc.Get("ui.media_stat_size"))
|
|
||||||
//line hypview/readers.qtpl:35
|
|
||||||
qw422016.N().S(`</b> `)
|
|
||||||
//line hypview/readers.qtpl:35
|
|
||||||
qw422016.E().S(lc.GetPlural64("ui.media_size_value", fileinfo.Size()))
|
|
||||||
//line hypview/readers.qtpl:35
|
|
||||||
qw422016.N().S(`</p>
|
|
||||||
<p><b>`)
|
|
||||||
//line hypview/readers.qtpl:36
|
|
||||||
qw422016.E().S(lc.Get("ui.media_stat_mime"))
|
|
||||||
//line hypview/readers.qtpl:36
|
|
||||||
qw422016.N().S(`</b> `)
|
|
||||||
//line hypview/readers.qtpl:36
|
|
||||||
qw422016.E().S(mime)
|
|
||||||
//line hypview/readers.qtpl:36
|
|
||||||
qw422016.N().S(`</p>
|
|
||||||
</fieldset>
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:38
|
|
||||||
}
|
|
||||||
//line hypview/readers.qtpl:38
|
|
||||||
qw422016.N().S(`
|
|
||||||
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:40
|
|
||||||
if strings.HasPrefix(mime, "image/") {
|
|
||||||
//line hypview/readers.qtpl:40
|
|
||||||
qw422016.N().S(`
|
|
||||||
<fieldset class="amnt-menu-block">
|
|
||||||
<legend class="modal__title modal__title_small">`)
|
|
||||||
//line hypview/readers.qtpl:42
|
|
||||||
qw422016.E().S(lc.Get("ui.media_include"))
|
|
||||||
//line hypview/readers.qtpl:42
|
|
||||||
qw422016.N().S(`</legend>
|
|
||||||
<p class="modal__confirmation-msg">`)
|
|
||||||
//line hypview/readers.qtpl:43
|
|
||||||
qw422016.E().S(lc.Get("ui.media_include_tip"))
|
|
||||||
//line hypview/readers.qtpl:43
|
|
||||||
qw422016.N().S(`</p>
|
|
||||||
<pre class="codeblock"><code>img { `)
|
|
||||||
//line hypview/readers.qtpl:44
|
|
||||||
qw422016.E().S(h.CanonicalName())
|
|
||||||
//line hypview/readers.qtpl:44
|
|
||||||
qw422016.N().S(` }</code></pre>
|
|
||||||
</fieldset>
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:46
|
|
||||||
}
|
|
||||||
//line hypview/readers.qtpl:46
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:47
|
|
||||||
}
|
|
||||||
//line hypview/readers.qtpl:47
|
|
||||||
qw422016.N().S(`
|
|
||||||
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:49
|
|
||||||
if u.CanProceed("upload-binary") {
|
|
||||||
//line hypview/readers.qtpl:49
|
|
||||||
qw422016.N().S(`
|
|
||||||
<form action="/upload-binary/`)
|
|
||||||
//line hypview/readers.qtpl:50
|
|
||||||
qw422016.E().S(h.CanonicalName())
|
|
||||||
//line hypview/readers.qtpl:50
|
|
||||||
qw422016.N().S(`"
|
|
||||||
method="post" enctype="multipart/form-data"
|
|
||||||
class="upload-binary modal amnt-menu-block">
|
|
||||||
<fieldset class="modal__fieldset">
|
|
||||||
<legend class="modal__title modal__title_small">`)
|
|
||||||
//line hypview/readers.qtpl:54
|
|
||||||
qw422016.E().S(lc.Get("ui.media_new"))
|
|
||||||
//line hypview/readers.qtpl:54
|
|
||||||
qw422016.N().S(`</legend>
|
|
||||||
<p class="modal__confirmation-msg">`)
|
|
||||||
//line hypview/readers.qtpl:55
|
|
||||||
qw422016.E().S(lc.Get("ui.media_new_tip"))
|
|
||||||
//line hypview/readers.qtpl:55
|
|
||||||
qw422016.N().S(`</p>
|
|
||||||
<label for="upload-binary__input"></label>
|
|
||||||
<input type="file" id="upload-binary__input" name="binary">
|
|
||||||
|
|
||||||
<button type="submit" class="btn stick-to-bottom" value="Upload">`)
|
|
||||||
//line hypview/readers.qtpl:59
|
|
||||||
qw422016.E().S(lc.Get("ui.media_upload"))
|
|
||||||
//line hypview/readers.qtpl:59
|
|
||||||
qw422016.N().S(`</button>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:62
|
|
||||||
}
|
|
||||||
//line hypview/readers.qtpl:62
|
|
||||||
qw422016.N().S(`
|
|
||||||
|
|
||||||
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:65
|
|
||||||
switch h := h.(type) {
|
|
||||||
//line hypview/readers.qtpl:66
|
|
||||||
case *hyphae.MediaHypha:
|
|
||||||
//line hypview/readers.qtpl:66
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:67
|
|
||||||
if u.CanProceed("remove-media") {
|
|
||||||
//line hypview/readers.qtpl:67
|
|
||||||
qw422016.N().S(`
|
|
||||||
<form action="/remove-media/`)
|
|
||||||
//line hypview/readers.qtpl:68
|
|
||||||
qw422016.E().S(h.CanonicalName())
|
|
||||||
//line hypview/readers.qtpl:68
|
|
||||||
qw422016.N().S(`" method="post" class="modal amnt-menu-block" method="POST">
|
|
||||||
<fieldset class="modal__fieldset">
|
|
||||||
<legend class="modal__title modal__title_small">`)
|
|
||||||
//line hypview/readers.qtpl:70
|
|
||||||
qw422016.E().S(lc.Get("ui.media_remove"))
|
|
||||||
//line hypview/readers.qtpl:70
|
|
||||||
qw422016.N().S(`</legend>
|
|
||||||
<p class="modal__confirmation-msg">`)
|
|
||||||
//line hypview/readers.qtpl:71
|
|
||||||
qw422016.E().S(lc.Get("ui.media_remove_tip"))
|
|
||||||
//line hypview/readers.qtpl:71
|
|
||||||
qw422016.N().S(`</p>
|
|
||||||
<button type="submit" class="btn" value="Remove media">`)
|
|
||||||
//line hypview/readers.qtpl:72
|
|
||||||
qw422016.E().S(lc.Get("ui.media_remove_button"))
|
|
||||||
//line hypview/readers.qtpl:72
|
|
||||||
qw422016.N().S(`</button>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:75
|
|
||||||
}
|
|
||||||
//line hypview/readers.qtpl:75
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:76
|
|
||||||
}
|
|
||||||
//line hypview/readers.qtpl:76
|
|
||||||
qw422016.N().S(`
|
|
||||||
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
func WriteMediaMenu(qq422016 qtio422016.Writer, rq *http.Request, h hyphae.Hypha, u *user.User) {
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
StreamMediaMenu(qw422016, rq, h, u)
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
qt422016.ReleaseWriter(qw422016)
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
func MediaMenu(rq *http.Request, h hyphae.Hypha, u *user.User) string {
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
WriteMediaMenu(qb422016, rq, h, u)
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
qs422016 := string(qb422016.B)
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
return qs422016
|
|
||||||
//line hypview/readers.qtpl:80
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:83
|
|
||||||
func StreamRevision(qw422016 *qt422016.Writer, meta viewutil.Meta, h hyphae.Hypha, contents, revHash string) {
|
|
||||||
//line hypview/readers.qtpl:83
|
|
||||||
qw422016.N().S(`
|
|
||||||
<main class="main-width">
|
|
||||||
<section>
|
|
||||||
<p>`)
|
|
||||||
//line hypview/readers.qtpl:86
|
|
||||||
qw422016.E().S(meta.Lc.Get("ui.revision_warning"))
|
|
||||||
//line hypview/readers.qtpl:86
|
|
||||||
qw422016.N().S(` <a href="/rev-text/`)
|
|
||||||
//line hypview/readers.qtpl:86
|
|
||||||
qw422016.E().S(revHash)
|
|
||||||
//line hypview/readers.qtpl:86
|
|
||||||
qw422016.N().S(`/`)
|
|
||||||
//line hypview/readers.qtpl:86
|
|
||||||
qw422016.E().S(h.CanonicalName())
|
|
||||||
//line hypview/readers.qtpl:86
|
|
||||||
qw422016.N().S(`">`)
|
|
||||||
//line hypview/readers.qtpl:86
|
|
||||||
qw422016.E().S(meta.Lc.Get("ui.revision_link"))
|
|
||||||
//line hypview/readers.qtpl:86
|
|
||||||
qw422016.N().S(`</a></p>
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:87
|
|
||||||
qw422016.N().S(NaviTitle(meta, h.CanonicalName()))
|
|
||||||
//line hypview/readers.qtpl:87
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:88
|
|
||||||
qw422016.N().S(contents)
|
|
||||||
//line hypview/readers.qtpl:88
|
|
||||||
qw422016.N().S(`
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:91
|
|
||||||
for _, scriptPath := range cfg.ViewScripts {
|
|
||||||
//line hypview/readers.qtpl:91
|
|
||||||
qw422016.N().S(`
|
|
||||||
<script src="`)
|
|
||||||
//line hypview/readers.qtpl:92
|
|
||||||
qw422016.E().S(scriptPath)
|
|
||||||
//line hypview/readers.qtpl:92
|
|
||||||
qw422016.N().S(`"></script>
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:93
|
|
||||||
}
|
|
||||||
//line hypview/readers.qtpl:93
|
|
||||||
qw422016.N().S(`
|
|
||||||
`)
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
func WriteRevision(qq422016 qtio422016.Writer, meta viewutil.Meta, h hyphae.Hypha, contents, revHash string) {
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
StreamRevision(qw422016, meta, h, contents, revHash)
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
qt422016.ReleaseWriter(qw422016)
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
}
|
|
||||||
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
func Revision(meta viewutil.Meta, h hyphae.Hypha, contents, revHash string) string {
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
WriteRevision(qb422016, meta, h, contents, revHash)
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
qs422016 := string(qb422016.B)
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
return qs422016
|
|
||||||
//line hypview/readers.qtpl:94
|
|
||||||
}
|
|
||||||
@ -4,18 +4,6 @@
|
|||||||
"title_search": "Search by title",
|
"title_search": "Search by title",
|
||||||
"admin_panel": "Admin panel",
|
"admin_panel": "Admin panel",
|
||||||
|
|
||||||
"edit_link": "Edit text",
|
|
||||||
"logout_link": "Log out",
|
|
||||||
"history_link": "View history",
|
|
||||||
"rename_link": "Rename",
|
|
||||||
"delete_link": "Delete",
|
|
||||||
"text_link": "View markup",
|
|
||||||
"media_link": "Manage media",
|
|
||||||
"media_link_for_textual": "Turn to media hypha",
|
|
||||||
"backlinks_link": "{{.n}} backlink%s",
|
|
||||||
"backlinks_link+one": "",
|
|
||||||
"backlinks_link+other": "s",
|
|
||||||
|
|
||||||
"subhyphae": "Subhyphae",
|
"subhyphae": "Subhyphae",
|
||||||
|
|
||||||
"random_no_hyphae": "There are no hyphae",
|
"random_no_hyphae": "There are no hyphae",
|
||||||
@ -57,9 +45,9 @@
|
|||||||
|
|
||||||
"diff_title": "Diff of {{.name}} at {{.rev}}",
|
"diff_title": "Diff of {{.name}} at {{.rev}}",
|
||||||
|
|
||||||
"revision_title": "{{.name}} at {{.rev}}",
|
"revision_title": "",
|
||||||
"revision_warning": "Please note that viewing media is not supported in history for now.",
|
"revision_warning": "",
|
||||||
"revision_link": "Get Mycomarkup source of this revision",
|
"revision_link": "",
|
||||||
"revision_no_text": "This hypha had no text at this revision.",
|
"revision_no_text": "This hypha had no text at this revision.",
|
||||||
|
|
||||||
"about_title": "About {{.name}}",
|
"about_title": "About {{.name}}",
|
||||||
@ -76,25 +64,6 @@
|
|||||||
"media_noaudio": "Your browser does not support audio.",
|
"media_noaudio": "Your browser does not support audio.",
|
||||||
"media_noaudio_link": "Download audio",
|
"media_noaudio_link": "Download audio",
|
||||||
|
|
||||||
"media_title": "Media of {{.name}}",
|
|
||||||
"media_empty": "This hypha has no media, you can upload it here.",
|
|
||||||
"media_tip": "You can manage the hypha's media on this page.",
|
|
||||||
"media_what_is": "What is media?",
|
|
||||||
"media_upload": "Upload",
|
|
||||||
"media_stat": "Stat",
|
|
||||||
"media_stat_size": "File size:",
|
|
||||||
"media_size_value": "{{.n}} byte%s",
|
|
||||||
"media_size_value+one": "",
|
|
||||||
"media_size_value+other": "s",
|
|
||||||
"media_stat_mime": "MIME type:",
|
|
||||||
"media_include": "Include",
|
|
||||||
"media_include_tip": "This media is an image. To include it in a hypha, use a syntax like this:",
|
|
||||||
"media_new": "media",
|
|
||||||
"media_new_tip": "You can upload a new media. Please do not upload too big pictures unless you need to because may not want to wait for big pictures to load.",
|
|
||||||
"media_remove": "Remove media",
|
|
||||||
"media_remove_tip": "Please note that you don't have to remove media before uploading a new media.",
|
|
||||||
"media_remove_button": "Remove media",
|
|
||||||
|
|
||||||
"confirm": "Confirm",
|
"confirm": "Confirm",
|
||||||
"cancel": "Cancel"
|
"cancel": "Cancel"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,14 +8,14 @@
|
|||||||
"backlinks_heading": "Обратные ссылки на {{.hypha_link}}",
|
"backlinks_heading": "Обратные ссылки на {{.hypha_link}}",
|
||||||
"backlinks_desc": "Ниже перечислены гифы, на которых есть ссылка на эту гифу, трансклюзия этой гифы или эта гифа вставлена как изображение.",
|
"backlinks_desc": "Ниже перечислены гифы, на которых есть ссылка на эту гифу, трансклюзия этой гифы или эта гифа вставлена как изображение.",
|
||||||
|
|
||||||
"edit_link": "Редактировать",
|
"edit_link": "",
|
||||||
"logout_link": "Выйти",
|
"logout_link": "",
|
||||||
"history_link": "История",
|
"history_link": "",
|
||||||
"rename_link": "Переименовать",
|
"rename_link": "",
|
||||||
"delete_link": "Удалить",
|
"delete_link": "",
|
||||||
"text_link": "Посмотреть разметку",
|
"text_link": "",
|
||||||
"media_link": "Медиа",
|
"media_link": "",
|
||||||
"media_link_for_textual": "Превратить в медиа-гифу",
|
"media_link_for_textual": "",
|
||||||
"backlinks_link": "{{.n}} %s сюда",
|
"backlinks_link": "{{.n}} %s сюда",
|
||||||
"backlinks_link+one": "ссылка",
|
"backlinks_link+one": "ссылка",
|
||||||
"backlinks_link+few": "ссылки",
|
"backlinks_link+few": "ссылки",
|
||||||
@ -59,9 +59,9 @@
|
|||||||
"ask_really": "Вы действительно хотите {{.verb}} гифу «{{.name}}»?",
|
"ask_really": "Вы действительно хотите {{.verb}} гифу «{{.name}}»?",
|
||||||
"ask_remove_media_verb": "убрать медиа",
|
"ask_remove_media_verb": "убрать медиа",
|
||||||
|
|
||||||
"revision_title": "{{.name}} из {{.rev}}",
|
"revision_title": "",
|
||||||
"revision_warning": "Обратите внимание, просмотр медиа в истории пока что недоступен.",
|
"revision_warning": "",
|
||||||
"revision_link": "Посмотреть Микоразметку для этой ревизии",
|
"revision_link": "",
|
||||||
"revision_no_text": "В этой ревизии гифы не было текста.",
|
"revision_no_text": "В этой ревизии гифы не было текста.",
|
||||||
|
|
||||||
"about_title": "О {{.name}}",
|
"about_title": "О {{.name}}",
|
||||||
@ -78,26 +78,6 @@
|
|||||||
"media_noaudio": "Ваш браузер не поддерживает аудио.",
|
"media_noaudio": "Ваш браузер не поддерживает аудио.",
|
||||||
"media_noaudio_link": "Скачать аудио",
|
"media_noaudio_link": "Скачать аудио",
|
||||||
|
|
||||||
"media_title": "Медиа «{{.name}}»",
|
|
||||||
"media_empty": "Эта гифа не имеет медиа, здесь вы можете его загрузить.",
|
|
||||||
"media_tip": "На этой странице вы можете управлять медиа.",
|
|
||||||
"media_what_is": "Что такое медиа?",
|
|
||||||
"media_upload": "Загрузить",
|
|
||||||
"media_stat": "Свойства",
|
|
||||||
"media_stat_size": "Размер файла:",
|
|
||||||
"media_size_value": "{{.n}} %s",
|
|
||||||
"media_size_value+one": "байт",
|
|
||||||
"media_size_value+few": "байта",
|
|
||||||
"media_size_value+many": "байт",
|
|
||||||
"media_stat_mime": "MIME-тип:",
|
|
||||||
"media_include": "Добавление",
|
|
||||||
"media_include_tip": "Это медиа – изображение. Чтобы добавить его в текст гифы, используйте синтаксис ниже:",
|
|
||||||
"media_new": "Прикрепить",
|
|
||||||
"media_new_tip": "Вы можете загрузить новое медиа. Пожалуйста, не загружайте слишком большие изображения без необходимости, чтобы впоследствии не ждать её долгую загрузку.",
|
|
||||||
"media_remove": "Открепить",
|
|
||||||
"media_remove_tip": "Заметьте, чтобы заменить медиа, вам не нужно его перед этим откреплять.",
|
|
||||||
"media_remove_button": "Открепить",
|
|
||||||
|
|
||||||
"confirm": "Применить",
|
"confirm": "Применить",
|
||||||
"cancel": "Отмена"
|
"cancel": "Отмена"
|
||||||
}
|
}
|
||||||
|
|||||||
1
main.go
1
main.go
@ -3,7 +3,6 @@
|
|||||||
//go:generate go run github.com/valyala/quicktemplate/qtc -dir=history
|
//go:generate go run github.com/valyala/quicktemplate/qtc -dir=history
|
||||||
//go:generate go run github.com/valyala/quicktemplate/qtc -dir=mycoopts
|
//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=auth
|
||||||
//go:generate go run github.com/valyala/quicktemplate/qtc -dir=hypview
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/bouncepaw/mycorrhiza/internal/cfg"
|
"github.com/bouncepaw/mycorrhiza/internal/cfg"
|
||||||
"github.com/bouncepaw/mycorrhiza/util"
|
"github.com/bouncepaw/mycorrhiza/util"
|
||||||
viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil"
|
"github.com/bouncepaw/mycorrhiza/web/viewutil"
|
||||||
"html/template"
|
"html/template"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -27,6 +27,15 @@ func NewPage(fs embed.FS, russianTranslation map[string]string, tmpls ...string)
|
|||||||
Funcs(template.FuncMap{
|
Funcs(template.FuncMap{
|
||||||
"beautifulName": util.BeautifulName,
|
"beautifulName": util.BeautifulName,
|
||||||
"inc": func(i int) int { return i + 1 },
|
"inc": func(i int) int { return i + 1 },
|
||||||
|
"base": func(hyphaName string) string {
|
||||||
|
parts := strings.Split(hyphaName, "/")
|
||||||
|
return parts[len(parts)-1]
|
||||||
|
},
|
||||||
|
"beautifulLink": func(hyphaName string) template.HTML {
|
||||||
|
return template.HTML(
|
||||||
|
fmt.Sprintf(
|
||||||
|
`<a href="/hypha/%s">%s</a>`, hyphaName, hyphaName))
|
||||||
|
},
|
||||||
}).
|
}).
|
||||||
Parse(fmt.Sprintf(`
|
Parse(fmt.Sprintf(`
|
||||||
{{define "wiki name"}}%s{{end}}
|
{{define "wiki name"}}%s{{end}}
|
||||||
@ -67,6 +76,13 @@ func NewPage(fs embed.FS, russianTranslation map[string]string, tmpls ...string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
russianTranslation["search by title"] = "Поиск по названию"
|
russianTranslation["search by title"] = "Поиск по названию"
|
||||||
|
russianTranslation["login"] = "Войти"
|
||||||
|
russianTranslation["register"] = "Регистрация"
|
||||||
|
russianTranslation["cancel"] = "Отмена"
|
||||||
|
russianTranslation["categories"] = "Категории"
|
||||||
|
russianTranslation["remove from category title"] = "Убрать гифу из этой категории"
|
||||||
|
russianTranslation["placeholder"] = "Название категории..."
|
||||||
|
russianTranslation["add to category title"] = "Добавить гифу в эту категорию"
|
||||||
|
|
||||||
return &Page{
|
return &Page{
|
||||||
TemplateEnglish: en,
|
TemplateEnglish: en,
|
||||||
@ -84,13 +100,13 @@ func translationsIntoTemplates(m map[string]string) string {
|
|||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Page) RenderTo(meta viewutil2.Meta, data map[string]any) error {
|
func (p *Page) RenderTo(meta viewutil.Meta, data map[string]any) error {
|
||||||
data["Meta"] = meta
|
data["Meta"] = meta
|
||||||
data["HeadElements"] = meta.HeadElements
|
data["HeadElements"] = meta.HeadElements
|
||||||
data["BodyAttributes"] = meta.BodyAttributes
|
data["BodyAttributes"] = meta.BodyAttributes
|
||||||
data["CommonScripts"] = cfg.CommonScripts
|
data["CommonScripts"] = cfg.CommonScripts
|
||||||
data["EditScripts"] = cfg.EditScripts
|
data["EditScripts"] = cfg.EditScripts
|
||||||
data["HeaderLinks"] = viewutil2.HeaderLinks
|
data["HeaderLinks"] = viewutil.HeaderLinks
|
||||||
|
|
||||||
tmpl := p.TemplateEnglish
|
tmpl := p.TemplateEnglish
|
||||||
if meta.LocaleIsRussian() {
|
if meta.LocaleIsRussian() {
|
||||||
|
|||||||
169
web/pages.go
169
web/pages.go
@ -11,6 +11,7 @@ var fs embed.FS
|
|||||||
|
|
||||||
var pageOrphans, pageBacklinks, pageUserList, pageChangePassword *newtmpl.Page
|
var pageOrphans, pageBacklinks, pageUserList, pageChangePassword *newtmpl.Page
|
||||||
var pageHyphaDelete, pageHyphaEdit, pageHyphaEmpty, pageHypha *newtmpl.Page
|
var pageHyphaDelete, pageHyphaEdit, pageHyphaEmpty, pageHypha *newtmpl.Page
|
||||||
|
var pageRevision, pageMedia *newtmpl.Page
|
||||||
var panelChain, listChain, newUserChain, editUserChain, deleteUserChain viewutil.Chain
|
var panelChain, listChain, newUserChain, editUserChain, deleteUserChain viewutil.Chain
|
||||||
|
|
||||||
func initPages() {
|
func initPages() {
|
||||||
@ -24,32 +25,19 @@ func initPages() {
|
|||||||
pageOrphans = newtmpl.NewPage(fs, map[string]string{
|
pageOrphans = newtmpl.NewPage(fs, map[string]string{
|
||||||
"orphaned hyphae": "Гифы-сироты",
|
"orphaned hyphae": "Гифы-сироты",
|
||||||
"orphan description": "Ниже перечислены гифы без ссылок на них.",
|
"orphan description": "Ниже перечислены гифы без ссылок на них.",
|
||||||
}, "views/orphans.html", map[string]string{
|
}, "views/orphans.html")
|
||||||
"orphaned hyphae": "Гифы-сироты",
|
|
||||||
"orphan description": "Ниже перечислены гифы без ссылок на них.",
|
|
||||||
})
|
|
||||||
pageBacklinks = newtmpl.NewPage(fs, map[string]string{
|
pageBacklinks = newtmpl.NewPage(fs, map[string]string{
|
||||||
"backlinks to text": `Обратные ссылки на {{.}}`,
|
"backlinks to text": `Обратные ссылки на {{.}}`,
|
||||||
"backlinks to link": `Обратные ссылки на <a href="/hypha/{{.}}">{{beautifulName .}}</a>`,
|
"backlinks to link": `Обратные ссылки на <a href="/hypha/{{.}}">{{beautifulName .}}</a>`,
|
||||||
"description": `Ниже перечислены гифы, на которых есть ссылка на эту гифу, трансклюзия этой гифы или эта гифа вставлена как изображение.`,
|
"description": `Ниже перечислены гифы, на которых есть ссылка на эту гифу, трансклюзия этой гифы или эта гифа вставлена как изображение.`,
|
||||||
}, "views/backlinks.html", map[string]string{
|
}, "views/backlinks.html")
|
||||||
"backlinks to text": `Обратные ссылки на {{.}}`,
|
|
||||||
"backlinks to link": `Обратные ссылки на <a href="/hypha/{{.}}">{{beautifulName .}}</a>`,
|
|
||||||
"description": `Ниже перечислены гифы, на которых есть ссылка на эту гифу, трансклюзия этой гифы или эта гифа вставлена как изображение.`,
|
|
||||||
})
|
|
||||||
pageUserList = newtmpl.NewPage(fs, map[string]string{
|
pageUserList = newtmpl.NewPage(fs, map[string]string{
|
||||||
"title": "Список пользователей",
|
"title": "Список пользователей",
|
||||||
"administrators": "Администраторы",
|
"administrators": "Администраторы",
|
||||||
"moderators": "Модераторы",
|
"moderators": "Модераторы",
|
||||||
"editors": "Редакторы",
|
"editors": "Редакторы",
|
||||||
"readers": "Читатели",
|
"readers": "Читатели",
|
||||||
}, "views/user-list.html", map[string]string{
|
}, "views/user-list.html")
|
||||||
"title": "Список пользователей",
|
|
||||||
"administrators": "Администраторы",
|
|
||||||
"moderators": "Модераторы",
|
|
||||||
"editors": "Редакторы",
|
|
||||||
"readers": "Читатели",
|
|
||||||
})
|
|
||||||
pageChangePassword = newtmpl.NewPage(fs, map[string]string{
|
pageChangePassword = newtmpl.NewPage(fs, map[string]string{
|
||||||
"change password": "Сменить пароль",
|
"change password": "Сменить пароль",
|
||||||
"confirm password": "Повторите пароль",
|
"confirm password": "Повторите пароль",
|
||||||
@ -57,25 +45,13 @@ func initPages() {
|
|||||||
"non local password change": "Пароль можно поменять только местным аккаунтам. Telegram-аккаунтам нельзя.",
|
"non local password change": "Пароль можно поменять только местным аккаунтам. Telegram-аккаунтам нельзя.",
|
||||||
"password": "Пароль",
|
"password": "Пароль",
|
||||||
"submit": "Поменять",
|
"submit": "Поменять",
|
||||||
}, "views/change-password.html", map[string]string{
|
}, "views/change-password.html")
|
||||||
"change password": "Сменить пароль",
|
|
||||||
"confirm password": "Повторите пароль",
|
|
||||||
"current password": "Текущий пароль",
|
|
||||||
"non local password change": "Пароль можно поменять только местным аккаунтам. Telegram-аккаунтам нельзя.",
|
|
||||||
"password": "Пароль",
|
|
||||||
"submit": "Поменять",
|
|
||||||
})
|
|
||||||
pageHyphaDelete = newtmpl.NewPage(fs, map[string]string{
|
pageHyphaDelete = newtmpl.NewPage(fs, map[string]string{
|
||||||
"delete hypha?": "Удалить {{beautifulName .}}?",
|
"delete hypha?": "Удалить {{beautifulName .}}?",
|
||||||
"delete [[hypha]]?": "Удалить <a href=\"/hypha/{{.}}\">{{beautifulName .}}</a>?",
|
"delete [[hypha]]?": "Удалить <a href=\"/hypha/{{.}}\">{{beautifulName .}}</a>?",
|
||||||
"want to delete?": "Вы действительно хотите удалить эту гифу?",
|
"want to delete?": "Вы действительно хотите удалить эту гифу?",
|
||||||
"delete tip": "Нельзя отменить удаление гифы, но её история останется доступной.",
|
"delete tip": "Нельзя отменить удаление гифы, но её история останется доступной.",
|
||||||
}, "views/hypha-delete.html", map[string]string{
|
}, "views/hypha-delete.html")
|
||||||
"delete hypha?": "Удалить {{beautifulName .}}?",
|
|
||||||
"delete [[hypha]]?": "Удалить <a href=\"/hypha/{{.}}\">{{beautifulName .}}</a>?",
|
|
||||||
"want to delete?": "Вы действительно хотите удалить эту гифу?",
|
|
||||||
"delete tip": "Нельзя отменить удаление гифы, но её история останется доступной.",
|
|
||||||
})
|
|
||||||
pageHyphaEdit = newtmpl.NewPage(fs, map[string]string{
|
pageHyphaEdit = newtmpl.NewPage(fs, map[string]string{
|
||||||
"editing hypha": `Редактирование {{beautifulName .}}`,
|
"editing hypha": `Редактирование {{beautifulName .}}`,
|
||||||
"editing [[hypha]]": `Редактирование <a href="/hypha/{{.}}">{{beautifulName .}}</a>`,
|
"editing [[hypha]]": `Редактирование <a href="/hypha/{{.}}">{{beautifulName .}}</a>`,
|
||||||
@ -87,65 +63,45 @@ func initPages() {
|
|||||||
"previewing hypha": `Предпросмотр «{{beautifulName .}}»`,
|
"previewing hypha": `Предпросмотр «{{beautifulName .}}»`,
|
||||||
"preview tip": `Заметьте, эта гифа ещё не сохранена. Вот её предпросмотр:`,
|
"preview tip": `Заметьте, эта гифа ещё не сохранена. Вот её предпросмотр:`,
|
||||||
|
|
||||||
"markup": `Разметка`,
|
"markup": `Разметка`,
|
||||||
"link": `Ссылка`,
|
"link": `Ссылка`,
|
||||||
"link title": `Текст`,
|
"link title": `Текст`,
|
||||||
"heading": `Заголовок`,
|
"heading": `Заголовок`,
|
||||||
"bold": `Жирный`,
|
"bold": `Жирный`,
|
||||||
"italic": `Курсив`,
|
"italic": `Курсив`,
|
||||||
"highlight": `Выделение`,
|
"highlight": `Выделение`,
|
||||||
"underline": `Подчеркивание`,
|
"underline": `Подчеркивание`,
|
||||||
"mono": `Моноширинный`,
|
"mono": `Моноширинный`,
|
||||||
"super": `Надстрочный`,
|
"super": `Надстрочный`,
|
||||||
"sub": `Подстрочный`,
|
"sub": `Подстрочный`,
|
||||||
"strike": `Зачёркнутый`,
|
"strike": `Зачёркнутый`,
|
||||||
"rocket": `Ссылка-ракета`,
|
"rocket": `Ссылка-ракета`,
|
||||||
"transclude": `Трансклюзия`,
|
"transclude": `Трансклюзия`,
|
||||||
"hr": `Гориз. черта`,
|
"hr": `Гориз. черта`,
|
||||||
"code": `Код-блок`,
|
"code": `Код-блок`,
|
||||||
"bullets": `Маркир. список`,
|
"bullets": `Маркир. список`,
|
||||||
"numbers": `Нумер. список`,
|
"numbers": `Нумер. список`,
|
||||||
"mycomarkup help": `<a href="/help/en/mycomarkup" class="shy-link">Подробнее</a> о Микоразметке`,
|
"mycomarkup help": `<a href="/help/en/mycomarkup" class="shy-link">Подробнее</a> о Микоразметке`,
|
||||||
"actions": `Действия`,
|
"actions": `Действия`,
|
||||||
"current date": `Текущая дата`,
|
"current date local": `Местная дата`,
|
||||||
"current time": `Текущее время`,
|
"current time local": `Местное время`,
|
||||||
"selflink": `Ссылка на вас`,
|
"current date utc": "Дата UTC",
|
||||||
}, "views/hypha-edit.html", map[string]string{
|
"current time utc": "Время UTC",
|
||||||
"editing hypha": `Редактирование {{beautifulName .}}`,
|
"selflink": `Ссылка на вас`,
|
||||||
"editing [[hypha]]": `Редактирование <a href="/hypha/{{.}}">{{beautifulName .}}</a>`,
|
}, "views/hypha-edit.html")
|
||||||
"creating [[hypha]]": `Создание <a href="/hypha/{{.}}">{{beautifulName .}}</a>`,
|
pageHypha = newtmpl.NewPage(fs, map[string]string{
|
||||||
"you're creating a new hypha": `Вы создаёте новую гифу.`,
|
"edit text": "Редактировать",
|
||||||
"describe your changes": `Опишите ваши правки`,
|
"log out": "Выйти",
|
||||||
"save": `Сохранить`,
|
"admin panel": "Админка",
|
||||||
"preview": `Предпросмотр`,
|
"subhyphae": "Подгифы",
|
||||||
"previewing hypha": `Предпросмотр «{{beautifulName .}}»`,
|
"history": "История",
|
||||||
"preview tip": `Заметьте, эта гифа ещё не сохранена. Вот её предпросмотр:`,
|
"rename": "Переименовать",
|
||||||
|
"delete": "Удалить",
|
||||||
|
"view markup": "Посмотреть разметку",
|
||||||
|
"manage media": "Медиа",
|
||||||
|
"turn to media": "Превратить в медиа-гифу",
|
||||||
|
"backlinks": "{{.BacklinkCount}} обратн{{if eq .BacklinkCount 1}}ая ссылка{{else if and (le .BacklinkCount 4) (gt .BacklinkCount 1)}}ые ссылки{{else}}ых ссылок{{end}}",
|
||||||
|
|
||||||
"markup": `Разметка`,
|
|
||||||
"link": `Ссылка`,
|
|
||||||
"link title": `Текст`,
|
|
||||||
"heading": `Заголовок`,
|
|
||||||
"bold": `Жирный`,
|
|
||||||
"italic": `Курсив`,
|
|
||||||
"highlight": `Выделение`,
|
|
||||||
"underline": `Подчеркивание`,
|
|
||||||
"mono": `Моноширинный`,
|
|
||||||
"super": `Надстрочный`,
|
|
||||||
"sub": `Подстрочный`,
|
|
||||||
"strike": `Зачёркнутый`,
|
|
||||||
"rocket": `Ссылка-ракета`,
|
|
||||||
"transclude": `Трансклюзия`,
|
|
||||||
"hr": `Гориз. черта`,
|
|
||||||
"code": `Код-блок`,
|
|
||||||
"bullets": `Маркир. список`,
|
|
||||||
"numbers": `Нумер. список`,
|
|
||||||
"mycomarkup help": `<a href="/help/en/mycomarkup" class="shy-link">Подробнее</a> о Микоразметке`,
|
|
||||||
"actions": `Действия`,
|
|
||||||
"current date": `Текущая дата`,
|
|
||||||
"current time": `Текущее время`,
|
|
||||||
"selflink": `Ссылка на вас`,
|
|
||||||
})
|
|
||||||
pageHyphaEmpty = newtmpl.NewPage(fs, map[string]string{
|
|
||||||
"empty heading": `Эта гифа не существует`,
|
"empty heading": `Эта гифа не существует`,
|
||||||
"empty no rights": `У вас нет прав для создания новых гиф. Вы можете:`,
|
"empty no rights": `У вас нет прав для создания новых гиф. Вы можете:`,
|
||||||
"empty log in": `Войти в свою учётную запись, если она у вас есть`,
|
"empty log in": `Войти в свою учётную запись, если она у вас есть`,
|
||||||
@ -157,18 +113,27 @@ func initPages() {
|
|||||||
"upload a media": `Загрузить медиа`,
|
"upload a media": `Загрузить медиа`,
|
||||||
"upload a media tip": `Загрузите изображение, видео или аудио. Распространённые форматы можно просматривать из браузера, остальные можно только скачать и просмотреть локально. Позже вы можете дописать пояснение к этому медиа.`,
|
"upload a media tip": `Загрузите изображение, видео или аудио. Распространённые форматы можно просматривать из браузера, остальные можно только скачать и просмотреть локально. Позже вы можете дописать пояснение к этому медиа.`,
|
||||||
"upload a media btn": `Загрузить`,
|
"upload a media btn": `Загрузить`,
|
||||||
}, "views/hypha-empty.html", map[string]string{
|
}, "views/hypha.html")
|
||||||
"empty heading": `Эта гифа не существует`,
|
pageRevision = newtmpl.NewPage(fs, map[string]string{
|
||||||
"empty no rights": `У вас нет прав для создания новых гиф. Вы можете:`,
|
"revision warning": "Обратите внимание, просмотр медиа в истории пока что недоступен.",
|
||||||
"empty log in": `Войти в свою учётную запись, если она у вас есть`,
|
"revision link": "Посмотреть Микоразметку для этой ревизии",
|
||||||
"empty register": `Создать новую учётную запись`,
|
"hypha at rev": "{{.HyphaName}} на {{.RevHash}}",
|
||||||
"write a text": `Написать текст`,
|
}, "views/hypha-revision.html")
|
||||||
"write a text tip": `Напишите заметку, дневник, статью, рассказ или иной текст с помощью <a href="/help/en/mycomarkup" class="shy-link">Микоразметки</a>. Сохраняется полная история правок документа.`,
|
pageMedia = newtmpl.NewPage(fs, map[string]string{ // TODO: сделать новый перевод
|
||||||
"write a text writing conventions": `Не забывайте следовать правилам оформления этой вики, если они имеются.`,
|
"media title": "Медиа «{{.HyphaName | beautifulLink}}»",
|
||||||
"write a text btn": `Создать`,
|
"tip": "На этой странице вы можете управлять медиа.",
|
||||||
"upload a media": `Загрузить медиа`,
|
"empty": "Эта гифа не имеет медиа, здесь вы можете его загрузить.",
|
||||||
"upload a media tip": `Загрузите изображение, видео или аудио. Распространённые форматы можно просматривать из браузера, остальные можно только скачать и просмотреть локально. Позже вы можете дописать пояснение к этому медиа.`,
|
"what is media?": "Что такое медиа?",
|
||||||
"upload a media btn": `Загрузить`,
|
"stat": "Свойства",
|
||||||
})
|
"stat size": "Размер файла:",
|
||||||
pageHypha = newtmpl.NewPage(fs, map[string]string{}, "views/hypha.html", map[string]string{})
|
"stat mime": "MIME-тип:",
|
||||||
|
|
||||||
|
"upload title": "Прикрепить",
|
||||||
|
"upload tip": "Вы можете загрузить новое медиа. Пожалуйста, не загружайте слишком большие изображения без необходимости, чтобы впоследствии не ждать её долгую загрузку.",
|
||||||
|
"upload btn": "Загрузить",
|
||||||
|
|
||||||
|
"remove title": "Открепить",
|
||||||
|
"remove tip": "Заметьте, чтобы заменить медиа, вам не нужно его перед этим откреплять.",
|
||||||
|
"remove btn": "Открепить",
|
||||||
|
}, "views/hypha-media.html")
|
||||||
}
|
}
|
||||||
|
|||||||
146
web/readers.go
146
web/readers.go
@ -17,8 +17,10 @@ import (
|
|||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -64,15 +66,31 @@ func handlerMedia(w http.ResponseWriter, rq *http.Request) {
|
|||||||
hyphaName = util.HyphaNameFromRq(rq, "media")
|
hyphaName = util.HyphaNameFromRq(rq, "media")
|
||||||
h = hyphae.ByName(hyphaName)
|
h = hyphae.ByName(hyphaName)
|
||||||
u = user.FromRequest(rq)
|
u = user.FromRequest(rq)
|
||||||
lc = l18n.FromRequest(rq)
|
isMedia = false
|
||||||
|
|
||||||
|
mime string
|
||||||
|
fileSize int64
|
||||||
)
|
)
|
||||||
util.HTTP200Page(w,
|
switch h := h.(type) {
|
||||||
viewutil.Base(
|
case *hyphae.MediaHypha:
|
||||||
viewutil.MetaFrom(w, rq),
|
isMedia = true
|
||||||
lc.Get("ui.media_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName)}),
|
mime = mimetype.FromExtension(path.Ext(h.MediaFilePath()))
|
||||||
hypview.MediaMenu(rq, h, u),
|
|
||||||
map[string]string{},
|
fileinfo, err := os.Stat(h.MediaFilePath())
|
||||||
))
|
if err != nil {
|
||||||
|
slog.Error("failed to stat media file", "err", err)
|
||||||
|
// no return
|
||||||
|
}
|
||||||
|
|
||||||
|
fileSize = fileinfo.Size()
|
||||||
|
}
|
||||||
|
_ = pageMedia.RenderTo(viewutil.MetaFrom(w, rq), map[string]any{
|
||||||
|
"HyphaName": h.CanonicalName(),
|
||||||
|
"U": u,
|
||||||
|
"IsMediaHypha": isMedia,
|
||||||
|
"MimeType": mime,
|
||||||
|
"FileSize": fileSize,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// handlerRevisionText sends Mycomarkup text of the hypha at the given revision. See also: handlerRevision, handlerText.
|
// handlerRevisionText sends Mycomarkup text of the hypha at the given revision. See also: handlerRevision, handlerText.
|
||||||
@ -137,7 +155,7 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
|
|||||||
var (
|
var (
|
||||||
hyphaName = util.CanonicalName(slug)
|
hyphaName = util.CanonicalName(slug)
|
||||||
h = hyphae.ByName(hyphaName)
|
h = hyphae.ByName(hyphaName)
|
||||||
contents = fmt.Sprintf(`<p>%s</p>`, lc.Get("ui.revision_no_text"))
|
contents = template.HTML(fmt.Sprintf(`<p>%s</p>`, lc.Get("ui.revision_no_text")))
|
||||||
textContents string
|
textContents string
|
||||||
err error
|
err error
|
||||||
mycoFilePath string
|
mycoFilePath string
|
||||||
@ -151,26 +169,17 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
|
|||||||
textContents, err = history.FileAtRevision(mycoFilePath, revHash)
|
textContents, err = history.FileAtRevision(mycoFilePath, revHash)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ctx, _ := mycocontext.ContextFromStringInput(textContents, mycoopts.MarkupOptions(hyphaName))
|
ctx, _ := mycocontext.ContextFromStringInput(textContents, mycoopts.MarkupOptions(hyphaName))
|
||||||
contents = mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx))
|
contents = template.HTML(mycomarkup.BlocksToHTML(ctx, mycomarkup.BlockTree(ctx)))
|
||||||
}
|
}
|
||||||
|
|
||||||
page := hypview.Revision(
|
meta := viewutil.MetaFrom(w, rq)
|
||||||
viewutil.MetaFrom(w, rq),
|
_ = pageRevision.RenderTo(meta, map[string]any{
|
||||||
h,
|
"ViewScripts": cfg.ViewScripts,
|
||||||
contents,
|
"Contents": contents,
|
||||||
revHash,
|
"RevHash": revHash,
|
||||||
)
|
"NaviTitle": hypview.NaviTitle(meta, h.CanonicalName()),
|
||||||
w.Header().Set("Content-Type", "text/html;charset=utf-8")
|
"HyphaName": h.CanonicalName(),
|
||||||
w.WriteHeader(http.StatusOK)
|
})
|
||||||
_, _ = fmt.Fprint(
|
|
||||||
w,
|
|
||||||
viewutil.Base(
|
|
||||||
viewutil.MetaFrom(w, rq),
|
|
||||||
lc.Get("ui.revision_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName), "rev": revHash}),
|
|
||||||
page,
|
|
||||||
map[string]string{},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// handlerText serves raw source text of the hypha.
|
// handlerText serves raw source text of the hypha.
|
||||||
@ -190,8 +199,7 @@ func handlerBinary(w http.ResponseWriter, rq *http.Request) {
|
|||||||
util.PrepareRq(rq)
|
util.PrepareRq(rq)
|
||||||
hyphaName := util.HyphaNameFromRq(rq, "binary")
|
hyphaName := util.HyphaNameFromRq(rq, "binary")
|
||||||
switch h := hyphae.ByName(hyphaName).(type) {
|
switch h := hyphae.ByName(hyphaName).(type) {
|
||||||
case *hyphae.EmptyHypha:
|
case *hyphae.EmptyHypha, *hyphae.TextualHypha:
|
||||||
case *hyphae.TextualHypha:
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
log.Printf("Textual hypha ‘%s’ has no media, cannot serve\n", h.CanonicalName())
|
log.Printf("Textual hypha ‘%s’ has no media, cannot serve\n", h.CanonicalName())
|
||||||
case *hyphae.MediaHypha:
|
case *hyphae.MediaHypha:
|
||||||
@ -205,59 +213,61 @@ func handlerBinary(w http.ResponseWriter, rq *http.Request) {
|
|||||||
func handlerHypha(w http.ResponseWriter, rq *http.Request) {
|
func handlerHypha(w http.ResponseWriter, rq *http.Request) {
|
||||||
util.PrepareRq(rq)
|
util.PrepareRq(rq)
|
||||||
var (
|
var (
|
||||||
hyphaName = util.HyphaNameFromRq(rq, "page", "hypha")
|
hyphaName = util.HyphaNameFromRq(rq, "page", "hypha")
|
||||||
h = hyphae.ByName(hyphaName)
|
h = hyphae.ByName(hyphaName)
|
||||||
contents string
|
contents template.HTML
|
||||||
openGraph string
|
openGraph template.HTML
|
||||||
lc = l18n.FromRequest(rq)
|
lc = l18n.FromRequest(rq)
|
||||||
|
meta = viewutil.MetaFrom(w, rq)
|
||||||
|
subhyphae, prevHyphaName, nextHyphaName = tree.Tree(h.CanonicalName())
|
||||||
|
cats = categories.CategoriesWithHypha(h.CanonicalName())
|
||||||
|
category_list = ":" + strings.Join(cats, ":") + ":"
|
||||||
|
isMyProfile = cfg.UseAuth && util.IsProfileName(h.CanonicalName()) && meta.U.Name == strings.TrimPrefix(h.CanonicalName(), cfg.UserHypha+"/")
|
||||||
|
|
||||||
|
data = map[string]any{
|
||||||
|
"HyphaName": h.CanonicalName(),
|
||||||
|
"SubhyphaeHTML": subhyphae,
|
||||||
|
"PrevHyphaName": prevHyphaName,
|
||||||
|
"NextHyphaName": nextHyphaName,
|
||||||
|
"IsMyProfile": isMyProfile,
|
||||||
|
"NaviTitle": hypview.NaviTitle(meta, h.CanonicalName()),
|
||||||
|
"BacklinkCount": backlinks.BacklinksCount(h.CanonicalName()),
|
||||||
|
"GivenPermissionToModify": user.CanProceed(rq, "edit"),
|
||||||
|
"Categories": cats,
|
||||||
|
"IsMediaHypha": false,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
slog.Info("reading hypha", "name", h.CanonicalName(), "can edit", data["GivenPermissionToModify"])
|
||||||
|
meta.BodyAttributes = map[string]string{
|
||||||
|
"cats": category_list,
|
||||||
|
}
|
||||||
|
|
||||||
switch h := h.(type) {
|
switch h := h.(type) {
|
||||||
case *hyphae.EmptyHypha:
|
case *hyphae.EmptyHypha:
|
||||||
// contents = hypview.EmptyHypha()
|
w.WriteHeader(http.StatusNotFound)
|
||||||
util.HTTP404Page(w,
|
data["Contents"] = ""
|
||||||
viewutil.Base(
|
_ = pageHypha.RenderTo(meta, data)
|
||||||
viewutil.MetaFrom(w, rq),
|
|
||||||
util.BeautifulName(hyphaName),
|
|
||||||
hypview.Hypha(viewutil.MetaFrom(w, rq), h, ""),
|
|
||||||
map[string]string{},
|
|
||||||
openGraph))
|
|
||||||
case hyphae.ExistingHypha:
|
case hyphae.ExistingHypha:
|
||||||
fileContentsT, errT := os.ReadFile(h.TextFilePath())
|
fileContentsT, err := os.ReadFile(h.TextFilePath())
|
||||||
if errT == nil {
|
if err == nil {
|
||||||
ctx, _ := mycocontext.ContextFromStringInput(string(fileContentsT), mycoopts.MarkupOptions(hyphaName))
|
ctx, _ := mycocontext.ContextFromStringInput(string(fileContentsT), mycoopts.MarkupOptions(hyphaName))
|
||||||
getOpenGraph, descVisitor, imgVisitor := tools.OpenGraphVisitors(ctx)
|
getOpenGraph, descVisitor, imgVisitor := tools.OpenGraphVisitors(ctx)
|
||||||
|
openGraph = template.HTML(getOpenGraph())
|
||||||
ast := mycomarkup.BlockTree(ctx, descVisitor, imgVisitor)
|
ast := mycomarkup.BlockTree(ctx, descVisitor, imgVisitor)
|
||||||
contents = mycomarkup.BlocksToHTML(ctx, ast)
|
contents = template.HTML(mycomarkup.BlocksToHTML(ctx, ast))
|
||||||
openGraph = getOpenGraph()
|
|
||||||
}
|
}
|
||||||
switch h := h.(type) {
|
switch h := h.(type) {
|
||||||
case *hyphae.MediaHypha:
|
case *hyphae.MediaHypha:
|
||||||
contents = mycoopts.Media(h, lc) + contents
|
contents = template.HTML(mycoopts.Media(h, lc)) + contents
|
||||||
|
data["IsMediaHypha"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
meta := viewutil.MetaFrom(w, rq)
|
data["Contents"] = contents
|
||||||
category_list := ":" + strings.Join(categories.CategoriesWithHypha(h.CanonicalName()), ":") + ":"
|
meta.HeadElements = append(meta.HeadElements, openGraph)
|
||||||
subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName())
|
_ = pageHypha.RenderTo(meta, data)
|
||||||
isMyProfile := cfg.UseAuth && util.IsProfileName(h.CanonicalName()) && meta.U.Name == strings.TrimPrefix(h.CanonicalName(), cfg.UserHypha+"/")
|
|
||||||
|
|
||||||
_ = pageHypha.RenderTo(
|
// TODO: check head cats
|
||||||
meta,
|
// TODO: check opengraph
|
||||||
map[string]any{
|
|
||||||
"SubhyphaeHTML": subhyphae,
|
|
||||||
"PrevHyphaName": prevHyphaName,
|
|
||||||
"NextHyphaName": nextHyphaName,
|
|
||||||
"IsMyProfile": isMyProfile,
|
|
||||||
"NaviTitle": hypview.NaviTitle(meta, h.CanonicalName()),
|
|
||||||
"Contents": template.HTML(contents),
|
|
||||||
})
|
|
||||||
util.HTTP200Page(w,
|
|
||||||
viewutil.Base(
|
|
||||||
viewutil.MetaFrom(w, rq),
|
|
||||||
util.BeautifulName(hyphaName),
|
|
||||||
hypview.Hypha(viewutil.MetaFrom(w, rq), h, contents),
|
|
||||||
map[string]string{"cats": category_list},
|
|
||||||
openGraph))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
{{define "empty hypha card"}}
|
|
||||||
<section class="non-existent-hypha">
|
|
||||||
<h2 class="non-existent-hypha__title">{{block "empty heading" .}}This hypha does not exist{{end}}</h2>
|
|
||||||
{{if and .UseAuth (eq .Meta.U.Group "anon")}}
|
|
||||||
<p>{{block "empty no rights" .}}You are not authorized to create new hyphae. Here is what you can do:{{end}}</p>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/login">{{block "empty log in" .}}Log in to your account, if you have one{{end}}</a></li>
|
|
||||||
{{if .AllowRegistration}}<li><a href="/register">{{block "empty register" .}}Register a new account{{end}}</a></li>{{end}}
|
|
||||||
</ul>
|
|
||||||
{{else}}
|
|
||||||
<div class="non-existent-hypha__ways">
|
|
||||||
<section class="non-existent-hypha__way">
|
|
||||||
<h3 class="non-existent-hypha__subtitle">📝 {{block "write a text" .}}Write a text{{end}}</h3>
|
|
||||||
<p>{{block "write a text tip" .}}Write a note, a diary, an article, a story or anything textual using <a href="/help/en/mycomarkup" class="shy-link">Mycomarkup</a>. Full history of edits to the document will be saved.{{end}}</p>
|
|
||||||
<p>{{block "write a text writing conventions" .}}Make sure to follow this wiki's writing conventions if there are any.{{end}}</p>
|
|
||||||
<a class="btn btn_accent stick-to-bottom" href="/edit/{{.HyphaName}}">{{block "write a text btn" .}}Create{{end}}</a>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="non-existent-hypha__way">
|
|
||||||
<h3 class="non-existent-hypha__subtitle">🖼 {{block "upload a media" .}}Upload a media{{end}}</h3>
|
|
||||||
<p>{{block "upload a media tip" .}}Upload a picture, a video or an audio. Most common formats can be viewed from the browser, others can only be downloaded and viewed locally. You can write a description for the media later.{{end}}</p>
|
|
||||||
<form action="/upload-binary/{{.HyphaName}}"
|
|
||||||
method="post" enctype="multipart/form-data"
|
|
||||||
class="upload-binary">
|
|
||||||
<input type="file" id="upload-binary__input" name="binary">
|
|
||||||
<button type="submit" class="btn stick-to-bottom" value="Upload">{{block "upload a media btn" .}}Upload{{end}}</button>
|
|
||||||
</form>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
</section>
|
|
||||||
{{end}}
|
|
||||||
57
web/views/hypha-media.html
Normal file
57
web/views/hypha-media.html
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{{define "title"}}{{end}}
|
||||||
|
{{define "body"}}
|
||||||
|
<main class="main-width media-tab">
|
||||||
|
<h1>{{block "media title" .}}Media of {{.HyphaName | beautifulLink }}{{end}}</h1>
|
||||||
|
<p class="explanation">
|
||||||
|
{{if .IsMediaHypha}}
|
||||||
|
{{block "tip" .}}You can manage the hypha's media on this page.{{end}}
|
||||||
|
{{else}}
|
||||||
|
{{block "empty" .}}This hypha has no media, you can upload it here.{{end}}
|
||||||
|
{{end}}
|
||||||
|
<a href="/help/en/media" class="shy-link">
|
||||||
|
{{block "what is media?" .}}What is media?{{end}}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<section class="amnt-grid">
|
||||||
|
{{if .IsMediaHypha}}
|
||||||
|
<fieldset class="amnt-menu-block"> <!-- TODO: refactor with <dl> -->
|
||||||
|
<legend class="modal__title modal__title_small">{{block "stat" .}}Stat{{end}}</legend>
|
||||||
|
<p><b>{{block "stat size" .}}File size:{{end}}</b> {{.FileSize}}</p> <!-- TODO: human readable measure -->
|
||||||
|
<p><b>{{block "stat mime" .}}MIME type:{{end}}</b> {{.MimeType}}</p>
|
||||||
|
</fieldset>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{if .U.CanProceed "upload-binary" }}
|
||||||
|
<form action="/upload-binary/{{.HyphaName}}"
|
||||||
|
method="post" enctype="multipart/form-data"
|
||||||
|
class="upload-binary modal amnt-menu-block">
|
||||||
|
<fieldset class="modal__fieldset">
|
||||||
|
<legend class="modal__title modal__title_small">
|
||||||
|
{{block "upload title" .}}Upload{{end}}</legend>
|
||||||
|
<p class="modal__confirmation-msg">
|
||||||
|
{{block "upload tip" .}}You can upload a new media. Please do not upload too big pictures unless you need to because may not want to wait for big pictures to load.{{end}}</p>
|
||||||
|
<label for="upload-binary__input"></label> <!-- TODO: ? -->
|
||||||
|
<input type="file" id="upload-binary__input" name="binary">
|
||||||
|
|
||||||
|
<button type="submit" class="btn stick-to-bottom" value="Upload">
|
||||||
|
{{block "upload btn" .}}Upload{{end}}</button>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{if .IsMediaHypha | and (.U.CanProceed "remove-media")}}
|
||||||
|
<form action="/remove-media/{{.HyphaName}}" class="modal amnt-menu-block" method="POST">
|
||||||
|
<fieldset class="modal__fieldset">
|
||||||
|
<legend class="modal__title modal__title_small">
|
||||||
|
{{block "remove title" .}}Remove media{{end}}</legend>
|
||||||
|
<p class="modal__confirmation-msg">
|
||||||
|
{{block "remove tip" .}}Please note that you don't have to remove media before uploading a new media.{{end}}</p>
|
||||||
|
<button type="submit" class="btn" value="Remove media">
|
||||||
|
{{block "remove btn" .}}Remove media{{end}}</button>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
{{end}}
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
{{end}}
|
||||||
18
web/views/hypha-revision.html
Normal file
18
web/views/hypha-revision.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{{define "hypha at rev"}}{{.HyphaName}} at {{.RevHash}}{{end}}
|
||||||
|
{{define "title"}}{{template "hypha at rev" .}}{{end}}
|
||||||
|
{{define "body"}}
|
||||||
|
<main class="main-width">
|
||||||
|
<section>
|
||||||
|
<p>
|
||||||
|
{{block "revision warning" .}}Please note that viewing media is not supported in history for now.{{end}}
|
||||||
|
<a href="/rev-text/{{.RevHash}}/{{.HyphaName}}">
|
||||||
|
{{block "revision link" .}}Get Mycomarkup source of this revision{{end}}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
{{.NaviTitle}}
|
||||||
|
{{.Contents}}
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
{{range .ViewScripts}}<script src="{{.}}"></script>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
@ -1,47 +1,44 @@
|
|||||||
|
{{define "title"}}{{.HyphaName | beautifulName}}{{end}}
|
||||||
|
|
||||||
{{define "body"}}
|
{{define "body"}}
|
||||||
<main class="main-width">
|
<main class="main-width">
|
||||||
<section id="hypha">
|
<section id="hypha">
|
||||||
{{if .Meta.U.CanProceed "edit"}}
|
{{if .Meta.U.CanProceed "edit"}}
|
||||||
<div class="btn btn_navititle">
|
<div class="btn btn_navititle">
|
||||||
<a class="btn__link_navititle" href="/edit/{{.HyphaName}}">
|
<a class="btn__link_navititle" href="/edit/{{.HyphaName}}">
|
||||||
{{block "edit" .}}Edit{{end}}
|
{{block "edit text" .}}Edit text{{end}}</a></div>
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{if .IsMyProfile}}
|
{{if .IsMyProfile}}
|
||||||
<div class="btn btn_navititle">
|
<div class="btn btn_navititle">
|
||||||
<a class="btn__link_navititle" href="/logout">
|
<a class="btn__link_navititle" href="/logout">
|
||||||
{{block "logout" .}}Log out{{end}}
|
{{block "log out" .}}Log out{{end}}</a></div>
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{{if eq .Meta.U.Group "admin"}}
|
{{if eq .Meta.U.Group "admin"}}
|
||||||
<div class="btn btn_navititle">
|
<div class="btn btn_navititle">
|
||||||
<a class="btn__link_navititle" href="/admin">
|
<a class="btn__link_navititle" href="/admin">
|
||||||
{{block "admin panel" .}}Admin panel{{end}}
|
{{block "admin panel" .}}Admin panel{{end}}</a></div>
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{.NaviTitle}}
|
{{.NaviTitle}}
|
||||||
{{.Contents}}
|
|
||||||
|
{{if .Contents}}{{.Contents}}{{else}}{{template "empty hypha card" .}}{{end}}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="prevnext">
|
<section class="prevnext">
|
||||||
{{if .PrevHyphaName}}
|
{{if .PrevHyphaName}}
|
||||||
<a class="prevnext__el prevnext__prev" href="/hypha/{{.PrevHyphaName}}" rel="prev">
|
<a class="prevnext__el prevnext__prev" href="/hypha/{{.PrevHyphaName}}" rel="prev">
|
||||||
← {{base .PrevHyphaName | beautifulName}}</a>
|
← {{.PrevHyphaName | base | beautifulName}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .NextHyphaName}}
|
{{if .NextHyphaName}}
|
||||||
<a class="prevnext__el prevnext__next" href="/hypha/{{.NextHyphaName}}" rel="next">
|
<a class="prevnext__el prevnext__next" href="/hypha/{{.NextHyphaName}}" rel="next">
|
||||||
{{base .NextHyphaName | beautifulName}} →</a>
|
{{.NextHyphaName | base | beautifulName}} →</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{{ if .SubhyphaeHTML }}
|
{{ if .SubhyphaeHTML }}
|
||||||
<section class="subhyphae">
|
<section class="subhyphae">
|
||||||
<h2 class="subhyphae__title">{%s lc.Get("ui.subhyphae") %}</h2>
|
<h2 class="subhyphae__title">{{block "subhyphae" .}}Subhyphae{{end}}</h2>
|
||||||
<nav class="subhyphae__nav">
|
<nav class="subhyphae__nav">
|
||||||
<ul class="subhyphae__list">
|
<ul class="subhyphae__list">
|
||||||
{{.SubhyphaeHTML}}
|
{{.SubhyphaeHTML}}
|
||||||
@ -51,12 +48,42 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<section id="hypha-bottom">
|
<section id="hypha-bottom">
|
||||||
{{hyphaInfo(meta, h)}}
|
<nav class="hypha-info">
|
||||||
|
<ul class="hypha-info__list">
|
||||||
|
<li class="hypha-info__entry hypha-info__entry_history">
|
||||||
|
<a class="hypha-info__link" href="/history/{{.HyphaName}}">
|
||||||
|
{{block "history" .}}View history{{end}}</a></li>
|
||||||
|
|
||||||
|
<li class="hypha-info__entry hypha-info__entry_rename">
|
||||||
|
<a class="hypha-info__link" href="/rename/{{.HyphaName}}">
|
||||||
|
{{block "rename" .}}Rename{{end}}</a></li>
|
||||||
|
|
||||||
|
<li class="hypha-info__entry hypha-info__entry_delete">
|
||||||
|
<a class="hypha-info__link" href="/delete/{{.HyphaName}}">
|
||||||
|
{{block "delete" .}}Delete{{end}}</a></li>
|
||||||
|
|
||||||
|
<li class="hypha-info__entry hypha-info__entry_text">
|
||||||
|
<a class="hypha-info__link" href="/text/{{.HyphaName}}">
|
||||||
|
{{block "view markup" .}}View markup{{end}}</a></li>
|
||||||
|
|
||||||
|
<li class="hypha-info__entry hypha-info__entry_media">
|
||||||
|
<a class="hypha-info__link" href="/media/{{.HyphaName}}">
|
||||||
|
{{- if .IsMediaHypha -}}
|
||||||
|
{{block "manage media" .}}Manage media{{end}}
|
||||||
|
{{- else -}}
|
||||||
|
{{block "turn to media" .}}Turn to media{{end}}
|
||||||
|
{{- end}}</a></li>
|
||||||
|
|
||||||
|
<li class="hypha-info__entry hypha-info__entry_backlinks">
|
||||||
|
<a class="hypha-info__link" href="/backlinks/{{.HyphaName}}">
|
||||||
|
{{block "backlinks" .}}backlink{{if gt .BacklinkCount 1}}s{{end}}{{end}}</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
{{template "category card" .}}
|
{{template "category card" .}}
|
||||||
{{range .ViewScripts}}<script src="{{.}}"></script>
|
{{range .ViewScripts}}<script src="{{.}}">
|
||||||
{{end}}
|
</script>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{define "category card"}}
|
{{define "category card"}}
|
||||||
@ -95,4 +122,39 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
</aside>
|
</aside>
|
||||||
{{end}}{{end}}
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
|
||||||
|
{{define "empty hypha card"}}
|
||||||
|
<section class="non-existent-hypha">
|
||||||
|
<h2 class="non-existent-hypha__title">{{block "empty heading" .}}This hypha does not exist{{end}}</h2>
|
||||||
|
{{if and .UseAuth (eq .Meta.U.Group "anon")}}
|
||||||
|
<p>{{block "empty no rights" .}}You are not authorized to create new hyphae. Here is what you can do:{{end}}</p>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/login">{{block "empty log in" .}}Log in to your account, if you have one{{end}}</a></li>
|
||||||
|
{{if .AllowRegistration}}<li><a href="/register">{{block "empty register" .}}Register a new account{{end}}</a></li>{{end}}
|
||||||
|
</ul>
|
||||||
|
{{else}}
|
||||||
|
<div class="non-existent-hypha__ways">
|
||||||
|
<section class="non-existent-hypha__way">
|
||||||
|
<h3 class="non-existent-hypha__subtitle">📝 {{block "write a text" .}}Write a text{{end}}</h3>
|
||||||
|
<p>{{block "write a text tip" .}}Write a note, a diary, an article, a story or anything textual using <a href="/help/en/mycomarkup" class="shy-link">Mycomarkup</a>. Full history of edits to the document will be saved.{{end}}</p>
|
||||||
|
<p>{{block "write a text writing conventions" .}}Make sure to follow this wiki's writing conventions if there are any.{{end}}</p>
|
||||||
|
<a class="btn btn_accent stick-to-bottom" href="/edit/{{.HyphaName}}">{{block "write a text btn" .}}Create{{end}}</a>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="non-existent-hypha__way">
|
||||||
|
<h3 class="non-existent-hypha__subtitle">🖼 {{block "upload a media" .}}Upload a media{{end}}</h3>
|
||||||
|
<p>{{block "upload a media tip" .}}Upload a picture, a video or an audio. Most common formats can be viewed from the browser, others can only be downloaded and viewed locally. You can write a description for the media later.{{end}}</p>
|
||||||
|
<form action="/upload-binary/{{.HyphaName}}"
|
||||||
|
method="post" enctype="multipart/form-data"
|
||||||
|
class="upload-binary">
|
||||||
|
<input type="file" id="upload-binary__input" name="binary">
|
||||||
|
<button type="submit" class="btn stick-to-bottom" value="Upload">{{block "upload a media btn" .}}Upload{{end}}</button>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</section>
|
||||||
|
{{end}}
|
||||||
@ -1,8 +1,9 @@
|
|||||||
package viewutil
|
package viewutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
user2 "github.com/bouncepaw/mycorrhiza/internal/user"
|
"github.com/bouncepaw/mycorrhiza/internal/user"
|
||||||
"github.com/bouncepaw/mycorrhiza/l18n"
|
"github.com/bouncepaw/mycorrhiza/l18n"
|
||||||
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
@ -10,12 +11,12 @@ import (
|
|||||||
// Meta is a bundle of common stuffs used by views, templates.
|
// Meta is a bundle of common stuffs used by views, templates.
|
||||||
type Meta struct {
|
type Meta struct {
|
||||||
Lc *l18n.Localizer
|
Lc *l18n.Localizer
|
||||||
U *user2.User
|
U *user.User
|
||||||
W io.Writer
|
W io.Writer
|
||||||
Addr string
|
Addr string
|
||||||
|
|
||||||
// New template additions
|
// New template additions
|
||||||
HeadElements []string
|
HeadElements []template.HTML
|
||||||
BodyAttributes map[string]string
|
BodyAttributes map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ type Meta struct {
|
|||||||
func MetaFrom(w http.ResponseWriter, rq *http.Request) Meta {
|
func MetaFrom(w http.ResponseWriter, rq *http.Request) Meta {
|
||||||
return Meta{
|
return Meta{
|
||||||
Lc: l18n.FromRequest(rq),
|
Lc: l18n.FromRequest(rq),
|
||||||
U: user2.FromRequest(rq),
|
U: user.FromRequest(rq),
|
||||||
W: w,
|
W: w,
|
||||||
Addr: rq.URL.Path,
|
Addr: rq.URL.Path,
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user