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())
-%}
-
-
- {%= 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)) %}
-
-
-{% 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: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(`
-
-
-`)
-//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 %}
-
- {% endif %}
-
- {% if strings.HasPrefix(mime, "image/") %}
-
- {% 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) %}
-
-
-
-{% 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: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: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: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}}
+
+ {{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"}}
+
+
+
+ {{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 .SubhyphaeHTML }}
- {%s lc.Get("ui.subhyphae") %}
+ {{block "subhyphae" .}}Subhyphae{{end}}
{{.SubhyphaeHTML}}
@@ -51,12 +48,42 @@
{{end}}
- {{hyphaInfo(meta, h)}}
+
+
+
{{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,
}