From ea1ae0d07837912b7fc48559b2ef031b84d0f5cb Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Fri, 12 Jul 2024 21:35:37 +0300 Subject: [PATCH] Megarefactoring of hypha views --- hypview/hypview.go | 7 +- hypview/nav.qtpl | 50 ----- hypview/nav.qtpl.go | 311 --------------------------- hypview/readers.qtpl | 94 --------- hypview/readers.qtpl.go | 382 ---------------------------------- l18n/en/ui.json | 37 +--- l18n/ru/ui.json | 42 +--- main.go | 1 - web/newtmpl/newtmpl.go | 22 +- web/pages.go | 169 ++++++--------- web/readers.go | 146 +++++++------ web/views/hypha-empty.html | 32 --- web/views/hypha-media.html | 57 +++++ web/views/hypha-revision.html | 18 ++ web/views/hypha.html | 96 +++++++-- web/viewutil/meta.go | 9 +- 16 files changed, 341 insertions(+), 1132 deletions(-) delete mode 100644 hypview/nav.qtpl delete mode 100644 hypview/nav.qtpl.go delete mode 100644 hypview/readers.qtpl delete mode 100644 hypview/readers.qtpl.go delete mode 100644 web/views/hypha-empty.html create mode 100644 web/views/hypha-media.html create mode 100644 web/views/hypha-revision.html diff --git a/hypview/hypview.go b/hypview/hypview.go index 6fdd26b..6881768 100644 --- a/hypview/hypview.go +++ b/hypview/hypview.go @@ -2,12 +2,13 @@ package hypview import ( "embed" - "github.com/bouncepaw/mycorrhiza/internal/backlinks" - "github.com/bouncepaw/mycorrhiza/internal/cfg" - "github.com/bouncepaw/mycorrhiza/web/viewutil" "html/template" "log" "strings" + + "github.com/bouncepaw/mycorrhiza/internal/backlinks" + "github.com/bouncepaw/mycorrhiza/internal/cfg" + "github.com/bouncepaw/mycorrhiza/web/viewutil" ) var ( diff --git a/hypview/nav.qtpl b/hypview/nav.qtpl deleted file mode 100644 index 3768edc..0000000 --- a/hypview/nav.qtpl +++ /dev/null @@ -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 %} -
  • - {%s displayText %} -
  • -{% endif %} -{% endfunc %} - -{% func hyphaInfo(meta viewutil.Meta, h hyphae.Hypha) %} -{% code - u := meta.U - lc := meta.Lc - backs := backlinks.BacklinksCount(h.CanonicalName()) -%} - -{% endfunc %} - -{% func commonScripts() %} -{% for _, scriptPath := range cfg.CommonScripts %} - -{% endfor %} -{% endfunc %} - -{% func beautifulLink(hyphaName string) %}{%s util.BeautifulName(hyphaName) %}{% endfunc %} diff --git a/hypview/nav.qtpl.go b/hypview/nav.qtpl.go deleted file mode 100644 index 965fbe6..0000000 --- a/hypview/nav.qtpl.go +++ /dev/null @@ -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(` -
  • - `) -//line hypview/nav.qtpl:16 - qw422016.E().S(displayText) -//line hypview/nav.qtpl:16 - qw422016.N().S(` -
  • -`) -//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(` - -`) -//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(` - -`) -//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(``) -//line hypview/nav.qtpl:50 - qw422016.E().S(util.BeautifulName(hyphaName)) -//line hypview/nav.qtpl:50 - qw422016.N().S(``) -//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 -} diff --git a/hypview/readers.qtpl b/hypview/readers.qtpl deleted file mode 100644 index c37eb1c..0000000 --- a/hypview/readers.qtpl +++ /dev/null @@ -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) -%} -
    -

    {%s= lc.Get("ui.media_title", &l18n.Replacements{"name": beautifulLink(h.CanonicalName())}) %}

    - {% switch h.(type) %} - {% case *hyphae.MediaHypha %} -

    {%s lc.Get("ui.media_tip") %} {%s lc.Get("ui.media_what_is") %}

    - {% default %} -

    {%s lc.Get("ui.media_empty") %} {%s lc.Get("ui.media_what_is") %}

    - {% endswitch %} - -
    - {% switch h := h.(type) %} - {% case *hyphae.MediaHypha %} - {% code - mime := mimetype.FromExtension(path.Ext(h.MediaFilePath())) - fileinfo, err := os.Stat(h.MediaFilePath()) %} - {% if err == nil %} -
    - {%s lc.Get("ui.media_stat") %} - -

    {%s lc.Get("ui.media_stat_mime") %} {%s mime %}

    -
    - {% endif %} - - {% if strings.HasPrefix(mime, "image/") %} -
    - {%s lc.Get("ui.media_include") %} - -
    img { {%s h.CanonicalName() %} }
    -
    - {% endif %} - {% endswitch %} - - {% if u.CanProceed("upload-binary") %} - - {% endif %} - - - {% switch h := h.(type) %} - {% case *hyphae.MediaHypha %} - {% if u.CanProceed("remove-media") %} - - {% endif %} - {% endswitch %} - -
    -
    -{% endfunc %} - - -{% func Revision(meta viewutil.Meta, h hyphae.Hypha, contents, revHash string) %} -
    -
    -

    {%s meta.Lc.Get("ui.revision_warning") %} {%s meta.Lc.Get("ui.revision_link") %}

    - {%s= NaviTitle(meta, h.CanonicalName()) %} - {%s= contents %} -
    -
    -{% for _, scriptPath := range cfg.ViewScripts %} - -{% endfor %} -{% endfunc %} diff --git a/hypview/readers.qtpl.go b/hypview/readers.qtpl.go deleted file mode 100644 index b87d96a..0000000 --- a/hypview/readers.qtpl.go +++ /dev/null @@ -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(` -
    -

    `) -//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(`

    - `) -//line hypview/readers.qtpl:19 - switch h.(type) { -//line hypview/readers.qtpl:20 - case *hyphae.MediaHypha: -//line hypview/readers.qtpl:20 - qw422016.N().S(` -

    `) -//line hypview/readers.qtpl:21 - qw422016.E().S(lc.Get("ui.media_tip")) -//line hypview/readers.qtpl:21 - qw422016.N().S(` `) -//line hypview/readers.qtpl:21 - qw422016.E().S(lc.Get("ui.media_what_is")) -//line hypview/readers.qtpl:21 - qw422016.N().S(`

    - `) -//line hypview/readers.qtpl:22 - default: -//line hypview/readers.qtpl:22 - qw422016.N().S(` -

    `) -//line hypview/readers.qtpl:23 - qw422016.E().S(lc.Get("ui.media_empty")) -//line hypview/readers.qtpl:23 - qw422016.N().S(` `) -//line hypview/readers.qtpl:23 - qw422016.E().S(lc.Get("ui.media_what_is")) -//line hypview/readers.qtpl:23 - qw422016.N().S(`

    - `) -//line hypview/readers.qtpl:24 - } -//line hypview/readers.qtpl:24 - qw422016.N().S(` - -
    - `) -//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(` -
    - `) -//line hypview/readers.qtpl:34 - qw422016.E().S(lc.Get("ui.media_stat")) -//line hypview/readers.qtpl:34 - qw422016.N().S(` - -

    `) -//line hypview/readers.qtpl:36 - qw422016.E().S(lc.Get("ui.media_stat_mime")) -//line hypview/readers.qtpl:36 - qw422016.N().S(` `) -//line hypview/readers.qtpl:36 - qw422016.E().S(mime) -//line hypview/readers.qtpl:36 - qw422016.N().S(`

    -
    - `) -//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(` -
    - `) -//line hypview/readers.qtpl:42 - qw422016.E().S(lc.Get("ui.media_include")) -//line hypview/readers.qtpl:42 - qw422016.N().S(` - -
    img { `)
    -//line hypview/readers.qtpl:44
    -			qw422016.E().S(h.CanonicalName())
    -//line hypview/readers.qtpl:44
    -			qw422016.N().S(` }
    -
    - `) -//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(` - - `) -//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(` - - `) -//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(` - -
    -
    -`) -//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(` -
    -
    -

    `) -//line hypview/readers.qtpl:86 - qw422016.E().S(meta.Lc.Get("ui.revision_warning")) -//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(`

    - `) -//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(` -
    -
    -`) -//line hypview/readers.qtpl:91 - for _, scriptPath := range cfg.ViewScripts { -//line hypview/readers.qtpl:91 - qw422016.N().S(` - -`) -//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 -} diff --git a/l18n/en/ui.json b/l18n/en/ui.json index 8350b05..23f9e55 100644 --- a/l18n/en/ui.json +++ b/l18n/en/ui.json @@ -4,18 +4,6 @@ "title_search": "Search by title", "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", "random_no_hyphae": "There are no hyphae", @@ -57,9 +45,9 @@ "diff_title": "Diff of {{.name}} at {{.rev}}", - "revision_title": "{{.name}} at {{.rev}}", - "revision_warning": "Please note that viewing media is not supported in history for now.", - "revision_link": "Get Mycomarkup source of this revision", + "revision_title": "", + "revision_warning": "", + "revision_link": "", "revision_no_text": "This hypha had no text at this revision.", "about_title": "About {{.name}}", @@ -76,25 +64,6 @@ "media_noaudio": "Your browser does not support 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", "cancel": "Cancel" } diff --git a/l18n/ru/ui.json b/l18n/ru/ui.json index 05b3c3a..c4006ba 100644 --- a/l18n/ru/ui.json +++ b/l18n/ru/ui.json @@ -8,14 +8,14 @@ "backlinks_heading": "Обратные ссылки на {{.hypha_link}}", "backlinks_desc": "Ниже перечислены гифы, на которых есть ссылка на эту гифу, трансклюзия этой гифы или эта гифа вставлена как изображение.", - "edit_link": "Редактировать", - "logout_link": "Выйти", - "history_link": "История", - "rename_link": "Переименовать", - "delete_link": "Удалить", - "text_link": "Посмотреть разметку", - "media_link": "Медиа", - "media_link_for_textual": "Превратить в медиа-гифу", + "edit_link": "", + "logout_link": "", + "history_link": "", + "rename_link": "", + "delete_link": "", + "text_link": "", + "media_link": "", + "media_link_for_textual": "", "backlinks_link": "{{.n}} %s сюда", "backlinks_link+one": "ссылка", "backlinks_link+few": "ссылки", @@ -59,9 +59,9 @@ "ask_really": "Вы действительно хотите {{.verb}} гифу «{{.name}}»?", "ask_remove_media_verb": "убрать медиа", - "revision_title": "{{.name}} из {{.rev}}", - "revision_warning": "Обратите внимание, просмотр медиа в истории пока что недоступен.", - "revision_link": "Посмотреть Микоразметку для этой ревизии", + "revision_title": "", + "revision_warning": "", + "revision_link": "", "revision_no_text": "В этой ревизии гифы не было текста.", "about_title": "О {{.name}}", @@ -78,26 +78,6 @@ "media_noaudio": "Ваш браузер не поддерживает аудио.", "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": "Применить", "cancel": "Отмена" } diff --git a/main.go b/main.go index 7bd28dd..c0b4ba7 100644 --- a/main.go +++ b/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=mycoopts //go:generate go run github.com/valyala/quicktemplate/qtc -dir=auth -//go:generate go run github.com/valyala/quicktemplate/qtc -dir=hypview package main import ( diff --git a/web/newtmpl/newtmpl.go b/web/newtmpl/newtmpl.go index ec309c2..b73b1cc 100644 --- a/web/newtmpl/newtmpl.go +++ b/web/newtmpl/newtmpl.go @@ -5,7 +5,7 @@ import ( "fmt" "github.com/bouncepaw/mycorrhiza/internal/cfg" "github.com/bouncepaw/mycorrhiza/util" - viewutil2 "github.com/bouncepaw/mycorrhiza/web/viewutil" + "github.com/bouncepaw/mycorrhiza/web/viewutil" "html/template" "strings" ) @@ -27,6 +27,15 @@ func NewPage(fs embed.FS, russianTranslation map[string]string, tmpls ...string) Funcs(template.FuncMap{ "beautifulName": util.BeautifulName, "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( + `%s`, hyphaName, hyphaName)) + }, }). Parse(fmt.Sprintf(` {{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["login"] = "Войти" + russianTranslation["register"] = "Регистрация" + russianTranslation["cancel"] = "Отмена" + russianTranslation["categories"] = "Категории" + russianTranslation["remove from category title"] = "Убрать гифу из этой категории" + russianTranslation["placeholder"] = "Название категории..." + russianTranslation["add to category title"] = "Добавить гифу в эту категорию" return &Page{ TemplateEnglish: en, @@ -84,13 +100,13 @@ func translationsIntoTemplates(m map[string]string) 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["HeadElements"] = meta.HeadElements data["BodyAttributes"] = meta.BodyAttributes data["CommonScripts"] = cfg.CommonScripts data["EditScripts"] = cfg.EditScripts - data["HeaderLinks"] = viewutil2.HeaderLinks + data["HeaderLinks"] = viewutil.HeaderLinks tmpl := p.TemplateEnglish if meta.LocaleIsRussian() { diff --git a/web/pages.go b/web/pages.go index ffef453..0598d3d 100644 --- a/web/pages.go +++ b/web/pages.go @@ -11,6 +11,7 @@ var fs embed.FS var pageOrphans, pageBacklinks, pageUserList, pageChangePassword *newtmpl.Page var pageHyphaDelete, pageHyphaEdit, pageHyphaEmpty, pageHypha *newtmpl.Page +var pageRevision, pageMedia *newtmpl.Page var panelChain, listChain, newUserChain, editUserChain, deleteUserChain viewutil.Chain func initPages() { @@ -24,32 +25,19 @@ func initPages() { pageOrphans = newtmpl.NewPage(fs, map[string]string{ "orphaned hyphae": "Гифы-сироты", "orphan description": "Ниже перечислены гифы без ссылок на них.", - }, "views/orphans.html", map[string]string{ - "orphaned hyphae": "Гифы-сироты", - "orphan description": "Ниже перечислены гифы без ссылок на них.", - }) + }, "views/orphans.html") pageBacklinks = newtmpl.NewPage(fs, map[string]string{ "backlinks to text": `Обратные ссылки на {{.}}`, "backlinks to link": `Обратные ссылки на {{beautifulName .}}`, "description": `Ниже перечислены гифы, на которых есть ссылка на эту гифу, трансклюзия этой гифы или эта гифа вставлена как изображение.`, - }, "views/backlinks.html", map[string]string{ - "backlinks to text": `Обратные ссылки на {{.}}`, - "backlinks to link": `Обратные ссылки на {{beautifulName .}}`, - "description": `Ниже перечислены гифы, на которых есть ссылка на эту гифу, трансклюзия этой гифы или эта гифа вставлена как изображение.`, - }) + }, "views/backlinks.html") pageUserList = newtmpl.NewPage(fs, map[string]string{ "title": "Список пользователей", "administrators": "Администраторы", "moderators": "Модераторы", "editors": "Редакторы", "readers": "Читатели", - }, "views/user-list.html", map[string]string{ - "title": "Список пользователей", - "administrators": "Администраторы", - "moderators": "Модераторы", - "editors": "Редакторы", - "readers": "Читатели", - }) + }, "views/user-list.html") pageChangePassword = newtmpl.NewPage(fs, map[string]string{ "change password": "Сменить пароль", "confirm password": "Повторите пароль", @@ -57,25 +45,13 @@ func initPages() { "non local password change": "Пароль можно поменять только местным аккаунтам. Telegram-аккаунтам нельзя.", "password": "Пароль", "submit": "Поменять", - }, "views/change-password.html", map[string]string{ - "change password": "Сменить пароль", - "confirm password": "Повторите пароль", - "current password": "Текущий пароль", - "non local password change": "Пароль можно поменять только местным аккаунтам. Telegram-аккаунтам нельзя.", - "password": "Пароль", - "submit": "Поменять", - }) + }, "views/change-password.html") pageHyphaDelete = newtmpl.NewPage(fs, map[string]string{ "delete hypha?": "Удалить {{beautifulName .}}?", "delete [[hypha]]?": "Удалить {{beautifulName .}}?", "want to delete?": "Вы действительно хотите удалить эту гифу?", "delete tip": "Нельзя отменить удаление гифы, но её история останется доступной.", - }, "views/hypha-delete.html", map[string]string{ - "delete hypha?": "Удалить {{beautifulName .}}?", - "delete [[hypha]]?": "Удалить {{beautifulName .}}?", - "want to delete?": "Вы действительно хотите удалить эту гифу?", - "delete tip": "Нельзя отменить удаление гифы, но её история останется доступной.", - }) + }, "views/hypha-delete.html") pageHyphaEdit = newtmpl.NewPage(fs, map[string]string{ "editing hypha": `Редактирование {{beautifulName .}}`, "editing [[hypha]]": `Редактирование {{beautifulName .}}`, @@ -87,65 +63,45 @@ func initPages() { "previewing hypha": `Предпросмотр «{{beautifulName .}}»`, "preview tip": `Заметьте, эта гифа ещё не сохранена. Вот её предпросмотр:`, - "markup": `Разметка`, - "link": `Ссылка`, - "link title": `Текст`, - "heading": `Заголовок`, - "bold": `Жирный`, - "italic": `Курсив`, - "highlight": `Выделение`, - "underline": `Подчеркивание`, - "mono": `Моноширинный`, - "super": `Надстрочный`, - "sub": `Подстрочный`, - "strike": `Зачёркнутый`, - "rocket": `Ссылка-ракета`, - "transclude": `Трансклюзия`, - "hr": `Гориз. черта`, - "code": `Код-блок`, - "bullets": `Маркир. список`, - "numbers": `Нумер. список`, - "mycomarkup help": `Подробнее о Микоразметке`, - "actions": `Действия`, - "current date": `Текущая дата`, - "current time": `Текущее время`, - "selflink": `Ссылка на вас`, - }, "views/hypha-edit.html", map[string]string{ - "editing hypha": `Редактирование {{beautifulName .}}`, - "editing [[hypha]]": `Редактирование {{beautifulName .}}`, - "creating [[hypha]]": `Создание {{beautifulName .}}`, - "you're creating a new hypha": `Вы создаёте новую гифу.`, - "describe your changes": `Опишите ваши правки`, - "save": `Сохранить`, - "preview": `Предпросмотр`, - "previewing hypha": `Предпросмотр «{{beautifulName .}}»`, - "preview tip": `Заметьте, эта гифа ещё не сохранена. Вот её предпросмотр:`, + "markup": `Разметка`, + "link": `Ссылка`, + "link title": `Текст`, + "heading": `Заголовок`, + "bold": `Жирный`, + "italic": `Курсив`, + "highlight": `Выделение`, + "underline": `Подчеркивание`, + "mono": `Моноширинный`, + "super": `Надстрочный`, + "sub": `Подстрочный`, + "strike": `Зачёркнутый`, + "rocket": `Ссылка-ракета`, + "transclude": `Трансклюзия`, + "hr": `Гориз. черта`, + "code": `Код-блок`, + "bullets": `Маркир. список`, + "numbers": `Нумер. список`, + "mycomarkup help": `Подробнее о Микоразметке`, + "actions": `Действия`, + "current date local": `Местная дата`, + "current time local": `Местное время`, + "current date utc": "Дата UTC", + "current time utc": "Время UTC", + "selflink": `Ссылка на вас`, + }, "views/hypha-edit.html") + pageHypha = newtmpl.NewPage(fs, map[string]string{ + "edit text": "Редактировать", + "log out": "Выйти", + "admin panel": "Админка", + "subhyphae": "Подгифы", + "history": "История", + "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": `Подробнее о Микоразметке`, - "actions": `Действия`, - "current date": `Текущая дата`, - "current time": `Текущее время`, - "selflink": `Ссылка на вас`, - }) - pageHyphaEmpty = newtmpl.NewPage(fs, map[string]string{ "empty heading": `Эта гифа не существует`, "empty no rights": `У вас нет прав для создания новых гиф. Вы можете:`, "empty log in": `Войти в свою учётную запись, если она у вас есть`, @@ -157,18 +113,27 @@ func initPages() { "upload a media": `Загрузить медиа`, "upload a media tip": `Загрузите изображение, видео или аудио. Распространённые форматы можно просматривать из браузера, остальные можно только скачать и просмотреть локально. Позже вы можете дописать пояснение к этому медиа.`, "upload a media btn": `Загрузить`, - }, "views/hypha-empty.html", map[string]string{ - "empty heading": `Эта гифа не существует`, - "empty no rights": `У вас нет прав для создания новых гиф. Вы можете:`, - "empty log in": `Войти в свою учётную запись, если она у вас есть`, - "empty register": `Создать новую учётную запись`, - "write a text": `Написать текст`, - "write a text tip": `Напишите заметку, дневник, статью, рассказ или иной текст с помощью Микоразметки. Сохраняется полная история правок документа.`, - "write a text writing conventions": `Не забывайте следовать правилам оформления этой вики, если они имеются.`, - "write a text btn": `Создать`, - "upload a media": `Загрузить медиа`, - "upload a media tip": `Загрузите изображение, видео или аудио. Распространённые форматы можно просматривать из браузера, остальные можно только скачать и просмотреть локально. Позже вы можете дописать пояснение к этому медиа.`, - "upload a media btn": `Загрузить`, - }) - pageHypha = newtmpl.NewPage(fs, map[string]string{}, "views/hypha.html", map[string]string{}) + }, "views/hypha.html") + pageRevision = newtmpl.NewPage(fs, map[string]string{ + "revision warning": "Обратите внимание, просмотр медиа в истории пока что недоступен.", + "revision link": "Посмотреть Микоразметку для этой ревизии", + "hypha at rev": "{{.HyphaName}} на {{.RevHash}}", + }, "views/hypha-revision.html") + pageMedia = newtmpl.NewPage(fs, map[string]string{ // TODO: сделать новый перевод + "media title": "Медиа «{{.HyphaName | beautifulLink}}»", + "tip": "На этой странице вы можете управлять медиа.", + "empty": "Эта гифа не имеет медиа, здесь вы можете его загрузить.", + "what is media?": "Что такое медиа?", + "stat": "Свойства", + "stat size": "Размер файла:", + "stat mime": "MIME-тип:", + + "upload title": "Прикрепить", + "upload tip": "Вы можете загрузить новое медиа. Пожалуйста, не загружайте слишком большие изображения без необходимости, чтобы впоследствии не ждать её долгую загрузку.", + "upload btn": "Загрузить", + + "remove title": "Открепить", + "remove tip": "Заметьте, чтобы заменить медиа, вам не нужно его перед этим откреплять.", + "remove btn": "Открепить", + }, "views/hypha-media.html") } diff --git a/web/readers.go b/web/readers.go index 16a058c..44e51ff 100644 --- a/web/readers.go +++ b/web/readers.go @@ -17,8 +17,10 @@ import ( "html/template" "io" "log" + "log/slog" "net/http" "os" + "path" "path/filepath" "strings" "time" @@ -64,15 +66,31 @@ func handlerMedia(w http.ResponseWriter, rq *http.Request) { hyphaName = util.HyphaNameFromRq(rq, "media") h = hyphae.ByName(hyphaName) u = user.FromRequest(rq) - lc = l18n.FromRequest(rq) + isMedia = false + + mime string + fileSize int64 ) - util.HTTP200Page(w, - viewutil.Base( - viewutil.MetaFrom(w, rq), - lc.Get("ui.media_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName)}), - hypview.MediaMenu(rq, h, u), - map[string]string{}, - )) + switch h := h.(type) { + case *hyphae.MediaHypha: + isMedia = true + mime = mimetype.FromExtension(path.Ext(h.MediaFilePath())) + + 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. @@ -137,7 +155,7 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) { var ( hyphaName = util.CanonicalName(slug) h = hyphae.ByName(hyphaName) - contents = fmt.Sprintf(`

    %s

    `, lc.Get("ui.revision_no_text")) + contents = template.HTML(fmt.Sprintf(`

    %s

    `, lc.Get("ui.revision_no_text"))) textContents string err error mycoFilePath string @@ -151,26 +169,17 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) { textContents, err = history.FileAtRevision(mycoFilePath, revHash) if err == nil { 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( - viewutil.MetaFrom(w, rq), - h, - contents, - revHash, - ) - w.Header().Set("Content-Type", "text/html;charset=utf-8") - 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{}, - ), - ) + meta := viewutil.MetaFrom(w, rq) + _ = pageRevision.RenderTo(meta, map[string]any{ + "ViewScripts": cfg.ViewScripts, + "Contents": contents, + "RevHash": revHash, + "NaviTitle": hypview.NaviTitle(meta, h.CanonicalName()), + "HyphaName": h.CanonicalName(), + }) } // handlerText serves raw source text of the hypha. @@ -190,8 +199,7 @@ func handlerBinary(w http.ResponseWriter, rq *http.Request) { util.PrepareRq(rq) hyphaName := util.HyphaNameFromRq(rq, "binary") switch h := hyphae.ByName(hyphaName).(type) { - case *hyphae.EmptyHypha: - case *hyphae.TextualHypha: + case *hyphae.EmptyHypha, *hyphae.TextualHypha: w.WriteHeader(http.StatusNotFound) log.Printf("Textual hypha ‘%s’ has no media, cannot serve\n", h.CanonicalName()) case *hyphae.MediaHypha: @@ -205,59 +213,61 @@ func handlerBinary(w http.ResponseWriter, rq *http.Request) { func handlerHypha(w http.ResponseWriter, rq *http.Request) { util.PrepareRq(rq) var ( - hyphaName = util.HyphaNameFromRq(rq, "page", "hypha") - h = hyphae.ByName(hyphaName) - contents string - openGraph string - lc = l18n.FromRequest(rq) + hyphaName = util.HyphaNameFromRq(rq, "page", "hypha") + h = hyphae.ByName(hyphaName) + contents template.HTML + openGraph template.HTML + 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) { case *hyphae.EmptyHypha: - // contents = hypview.EmptyHypha() - util.HTTP404Page(w, - viewutil.Base( - viewutil.MetaFrom(w, rq), - util.BeautifulName(hyphaName), - hypview.Hypha(viewutil.MetaFrom(w, rq), h, ""), - map[string]string{}, - openGraph)) + w.WriteHeader(http.StatusNotFound) + data["Contents"] = "" + _ = pageHypha.RenderTo(meta, data) case hyphae.ExistingHypha: - fileContentsT, errT := os.ReadFile(h.TextFilePath()) - if errT == nil { + fileContentsT, err := os.ReadFile(h.TextFilePath()) + if err == nil { ctx, _ := mycocontext.ContextFromStringInput(string(fileContentsT), mycoopts.MarkupOptions(hyphaName)) getOpenGraph, descVisitor, imgVisitor := tools.OpenGraphVisitors(ctx) + openGraph = template.HTML(getOpenGraph()) ast := mycomarkup.BlockTree(ctx, descVisitor, imgVisitor) - contents = mycomarkup.BlocksToHTML(ctx, ast) - openGraph = getOpenGraph() + contents = template.HTML(mycomarkup.BlocksToHTML(ctx, ast)) } switch h := h.(type) { 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) - category_list := ":" + strings.Join(categories.CategoriesWithHypha(h.CanonicalName()), ":") + ":" - subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName()) - isMyProfile := cfg.UseAuth && util.IsProfileName(h.CanonicalName()) && meta.U.Name == strings.TrimPrefix(h.CanonicalName(), cfg.UserHypha+"/") + data["Contents"] = contents + meta.HeadElements = append(meta.HeadElements, openGraph) + _ = pageHypha.RenderTo(meta, data) - _ = pageHypha.RenderTo( - meta, - 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)) + // TODO: check head cats + // TODO: check opengraph } } diff --git a/web/views/hypha-empty.html b/web/views/hypha-empty.html deleted file mode 100644 index 2af3638..0000000 --- a/web/views/hypha-empty.html +++ /dev/null @@ -1,32 +0,0 @@ -{{define "empty hypha card"}} -
    -

    {{block "empty heading" .}}This hypha does not exist{{end}}

    - {{if and .UseAuth (eq .Meta.U.Group "anon")}} -

    {{block "empty no rights" .}}You are not authorized to create new hyphae. Here is what you can do:{{end}}

    - - {{else}} -
    -
    -

    📝 {{block "write a text" .}}Write a text{{end}}

    -

    {{block "write a text tip" .}}Write a note, a diary, an article, a story or anything textual using Mycomarkup. Full history of edits to the document will be saved.{{end}}

    -

    {{block "write a text writing conventions" .}}Make sure to follow this wiki's writing conventions if there are any.{{end}}

    - {{block "write a text btn" .}}Create{{end}} -
    - -
    -

    🖼 {{block "upload a media" .}}Upload a media{{end}}

    -

    {{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}}

    -
    - - -
    -
    -
    - {{end}} -
    -{{end}} \ No newline at end of file diff --git a/web/views/hypha-media.html b/web/views/hypha-media.html new file mode 100644 index 0000000..c3c4d49 --- /dev/null +++ b/web/views/hypha-media.html @@ -0,0 +1,57 @@ +{{define "title"}}{{end}} +{{define "body"}} +
    +

    {{block "media title" .}}Media of {{.HyphaName | beautifulLink }}{{end}}

    +

    + {{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}} + + {{block "what is media?" .}}What is media?{{end}} + +

    + +
    + {{if .IsMediaHypha}} +
    + {{block "stat" .}}Stat{{end}} +

    {{block "stat size" .}}File size:{{end}} {{.FileSize}}

    +

    {{block "stat mime" .}}MIME type:{{end}} {{.MimeType}}

    +
    + {{end}} + + {{if .U.CanProceed "upload-binary" }} + + {{end}} + + {{if .IsMediaHypha | and (.U.CanProceed "remove-media")}} + + {{end}} +
    +
    +{{end}} \ No newline at end of file diff --git a/web/views/hypha-revision.html b/web/views/hypha-revision.html new file mode 100644 index 0000000..d17bbee --- /dev/null +++ b/web/views/hypha-revision.html @@ -0,0 +1,18 @@ +{{define "hypha at rev"}}{{.HyphaName}} at {{.RevHash}}{{end}} +{{define "title"}}{{template "hypha at rev" .}}{{end}} +{{define "body"}} +
    +
    +

    + {{block "revision warning" .}}Please note that viewing media is not supported in history for now.{{end}} + + {{block "revision link" .}}Get Mycomarkup source of this revision{{end}} + +

    + {{.NaviTitle}} + {{.Contents}} +
    +
    + {{range .ViewScripts}} + {{end}} +{{end}} \ No newline at end of file diff --git a/web/views/hypha.html b/web/views/hypha.html index 5721245..b5afc83 100644 --- a/web/views/hypha.html +++ b/web/views/hypha.html @@ -1,47 +1,44 @@ +{{define "title"}}{{.HyphaName | beautifulName}}{{end}} + {{define "body"}}
    {{if .Meta.U.CanProceed "edit"}} + {{block "edit text" .}}Edit text{{end}} {{end}} {{if .IsMyProfile}} + {{block "log out" .}}Log out{{end}} {{if eq .Meta.U.Group "admin"}} + {{block "admin panel" .}}Admin panel{{end}} {{end}} {{end}} {{.NaviTitle}} - {{.Contents}} + + {{if .Contents}}{{.Contents}}{{else}}{{template "empty hypha card" .}}{{end}}
    {{if .PrevHyphaName}} + ← {{.PrevHyphaName | base | beautifulName}} {{end}} {{if .NextHyphaName}} + {{.NextHyphaName | base | beautifulName}} → {{end}}
    {{ if .SubhyphaeHTML }}
    -

    {%s lc.Get("ui.subhyphae") %}

    +

    {{block "subhyphae" .}}Subhyphae{{end}}

    {{template "category card" .}} - {{range .ViewScripts}} - {{end}} + {{range .ViewScripts}}{{end}} {{end}} {{define "category card"}} @@ -95,4 +122,39 @@ {{end}} - {{end}}{{end}} + {{end}} +{{end}} + + +{{define "empty hypha card"}} +
    +

    {{block "empty heading" .}}This hypha does not exist{{end}}

    + {{if and .UseAuth (eq .Meta.U.Group "anon")}} +

    {{block "empty no rights" .}}You are not authorized to create new hyphae. Here is what you can do:{{end}}

    + + {{else}} +
    +
    +

    📝 {{block "write a text" .}}Write a text{{end}}

    +

    {{block "write a text tip" .}}Write a note, a diary, an article, a story or anything textual using Mycomarkup. Full history of edits to the document will be saved.{{end}}

    +

    {{block "write a text writing conventions" .}}Make sure to follow this wiki's writing conventions if there are any.{{end}}

    + {{block "write a text btn" .}}Create{{end}} +
    + +
    +

    🖼 {{block "upload a media" .}}Upload a media{{end}}

    +

    {{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}}

    +
    + + +
    +
    +
    + {{end}} +
    +{{end}} \ No newline at end of file diff --git a/web/viewutil/meta.go b/web/viewutil/meta.go index 8d88eb9..d47dc02 100644 --- a/web/viewutil/meta.go +++ b/web/viewutil/meta.go @@ -1,8 +1,9 @@ package viewutil import ( - user2 "github.com/bouncepaw/mycorrhiza/internal/user" + "github.com/bouncepaw/mycorrhiza/internal/user" "github.com/bouncepaw/mycorrhiza/l18n" + "html/template" "io" "net/http" ) @@ -10,12 +11,12 @@ import ( // Meta is a bundle of common stuffs used by views, templates. type Meta struct { Lc *l18n.Localizer - U *user2.User + U *user.User W io.Writer Addr string // New template additions - HeadElements []string + HeadElements []template.HTML BodyAttributes map[string]string } @@ -23,7 +24,7 @@ type Meta struct { func MetaFrom(w http.ResponseWriter, rq *http.Request) Meta { return Meta{ Lc: l18n.FromRequest(rq), - U: user2.FromRequest(rq), + U: user.FromRequest(rq), W: w, Addr: rq.URL.Path, }