diff --git a/main.go b/main.go index bfa549c..40a1f9e 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ package main import ( "github.com/bouncepaw/mycorrhiza/hyphae/categories" "github.com/bouncepaw/mycorrhiza/migration" + "github.com/bouncepaw/mycorrhiza/viewutil" "log" "os" @@ -41,6 +42,7 @@ func main() { log.Println("Using Git storage at", files.HyphaeDir()) // Init the subsystems: + viewutil.Init() hyphae.Index(files.HyphaeDir()) backlinks.IndexBacklinks() go backlinks.RunBacklinksConveyor() diff --git a/views/admin.go b/views/admin.go index dd89e2b..3a383d2 100644 --- a/views/admin.go +++ b/views/admin.go @@ -2,6 +2,7 @@ package views import ( "github.com/bouncepaw/mycorrhiza/util" + "github.com/bouncepaw/mycorrhiza/viewutil" "html/template" "io" "log" @@ -25,7 +26,7 @@ var ( adminTemplatesRu *template.Template ) -func localizedAdminTemplates(meta Meta) *template.Template { +func localizedAdminTemplates(meta viewutil.Meta) *template.Template { if meta.Lc.Locale == "ru" { return adminTemplatesRu } @@ -59,7 +60,7 @@ func init() { template.Must(adminTemplatesEn.Clone()).Parse(adminTranslationRu)) } -func AdminPanel(meta Meta) { +func AdminPanel(meta viewutil.Meta) { var buf strings.Builder err := localizedAdminTemplates(meta).ExecuteTemplate(&buf, "panel", nil) if err != nil { diff --git a/views/base.go b/views/base.go index df5464c..1fc4ccd 100644 --- a/views/base.go +++ b/views/base.go @@ -2,28 +2,7 @@ package views import ( "embed" - "github.com/bouncepaw/mycorrhiza/l18n" - "github.com/bouncepaw/mycorrhiza/user" - "io" - "net/http" ) -// Meta is a bundle of common stuffs used by views, templates. -type Meta struct { - Lc *l18n.Localizer - U *user.User - W io.Writer - PageTitle string -} - -// MetaFrom makes a Meta from the given data. You are meant to further modify it. -func MetaFrom(w http.ResponseWriter, rq *http.Request) Meta { - return Meta{ - Lc: l18n.FromRequest(rq), - U: user.FromRequest(rq), - W: w, - } -} - //go:embed *.html var fs embed.FS diff --git a/views/categories.go b/views/categories.go index f377a73..665ac0f 100644 --- a/views/categories.go +++ b/views/categories.go @@ -3,6 +3,7 @@ package views import ( "github.com/bouncepaw/mycorrhiza/hyphae/categories" "github.com/bouncepaw/mycorrhiza/util" + "github.com/bouncepaw/mycorrhiza/viewutil" "html/template" "io" "log" @@ -39,14 +40,14 @@ func init() { categoryTemplatesRu = template.Must(template.Must(categoryTemplatesEn.Clone()).Parse(categoriesRu)) } -func localizedCatTemplates(meta Meta) *template.Template { +func localizedCatTemplates(meta viewutil.Meta) *template.Template { if meta.Lc.Locale == "ru" { return categoryTemplatesRu } return categoryTemplatesEn } -func localizedCatTemplateAsString(meta Meta, name string, datum ...interface{}) string { +func localizedCatTemplateAsString(meta viewutil.Meta, name string, datum ...interface{}) string { var buf strings.Builder var err error if len(datum) == 1 { @@ -61,7 +62,7 @@ func localizedCatTemplateAsString(meta Meta, name string, datum ...interface{}) return buf.String() } -func categoryCard(meta Meta, hyphaName string) string { +func categoryCard(meta viewutil.Meta, hyphaName string) string { var buf strings.Builder err := localizedCatTemplates(meta).ExecuteTemplate(&buf, "category card", struct { HyphaName string @@ -78,7 +79,7 @@ func categoryCard(meta Meta, hyphaName string) string { return buf.String() } -func CategoryPage(meta Meta, catName string) { +func CategoryPage(meta viewutil.Meta, catName string) { var buf strings.Builder err := localizedCatTemplates(meta).ExecuteTemplate(&buf, "category page", struct { CatName string @@ -103,7 +104,7 @@ func CategoryPage(meta Meta, catName string) { } } -func CategoryList(meta Meta) { +func CategoryList(meta viewutil.Meta) { var buf strings.Builder err := localizedCatTemplates(meta).ExecuteTemplate(&buf, "category list", struct { Categories []string diff --git a/views/nav.qtpl b/views/nav.qtpl index 097c7f1..132beb3 100644 --- a/views/nav.qtpl +++ b/views/nav.qtpl @@ -4,6 +4,7 @@ {% import "github.com/bouncepaw/mycorrhiza/l18n" %} {% import "github.com/bouncepaw/mycorrhiza/user" %} {% import "github.com/bouncepaw/mycorrhiza/hyphae" %} +{% import "github.com/bouncepaw/mycorrhiza/viewutil" %} {% func hyphaInfoEntry(h hyphae.Hypha, u *user.User, action, displayText string) %} {% if u.CanProceed(action) %} @@ -13,7 +14,7 @@ {% endif %} {% endfunc %} -{% func hyphaInfo(meta Meta, h hyphae.Hypha) %} +{% func hyphaInfo(meta viewutil.Meta, h hyphae.Hypha) %} {% code u := meta.U lc := meta.Lc diff --git a/views/nav.qtpl.go b/views/nav.qtpl.go index ee546a7..3965210 100644 --- a/views/nav.qtpl.go +++ b/views/nav.qtpl.go @@ -22,270 +22,273 @@ import "github.com/bouncepaw/mycorrhiza/user" //line views/nav.qtpl:6 import "github.com/bouncepaw/mycorrhiza/hyphae" -//line views/nav.qtpl:8 +//line views/nav.qtpl:7 +import "github.com/bouncepaw/mycorrhiza/viewutil" + +//line views/nav.qtpl:9 import ( qtio422016 "io" qt422016 "github.com/valyala/quicktemplate" ) -//line views/nav.qtpl:8 +//line views/nav.qtpl:9 var ( _ = qtio422016.Copy _ = qt422016.AcquireByteBuffer ) -//line views/nav.qtpl:8 +//line views/nav.qtpl:9 func streamhyphaInfoEntry(qw422016 *qt422016.Writer, h hyphae.Hypha, u *user.User, action, displayText string) { -//line views/nav.qtpl:8 +//line views/nav.qtpl:9 qw422016.N().S(` `) -//line views/nav.qtpl:9 +//line views/nav.qtpl:10 if u.CanProceed(action) { -//line views/nav.qtpl:9 +//line views/nav.qtpl:10 qw422016.N().S(`
  • `) -//line views/nav.qtpl:11 +//line views/nav.qtpl:12 qw422016.E().S(displayText) -//line views/nav.qtpl:11 +//line views/nav.qtpl:12 qw422016.N().S(`
  • `) -//line views/nav.qtpl:13 +//line views/nav.qtpl:14 } -//line views/nav.qtpl:13 +//line views/nav.qtpl:14 qw422016.N().S(` `) -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 } -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 func writehyphaInfoEntry(qq422016 qtio422016.Writer, h hyphae.Hypha, u *user.User, action, displayText string) { -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 streamhyphaInfoEntry(qw422016, h, u, action, displayText) -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 qt422016.ReleaseWriter(qw422016) -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 } -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 func hyphaInfoEntry(h hyphae.Hypha, u *user.User, action, displayText string) string { -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 qb422016 := qt422016.AcquireByteBuffer() -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 writehyphaInfoEntry(qb422016, h, u, action, displayText) -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 qs422016 := string(qb422016.B) -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 qt422016.ReleaseByteBuffer(qb422016) -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 return qs422016 -//line views/nav.qtpl:14 +//line views/nav.qtpl:15 } -//line views/nav.qtpl:16 -func streamhyphaInfo(qw422016 *qt422016.Writer, meta Meta, h hyphae.Hypha) { -//line views/nav.qtpl:16 +//line views/nav.qtpl:17 +func streamhyphaInfo(qw422016 *qt422016.Writer, meta viewutil.Meta, h hyphae.Hypha) { +//line views/nav.qtpl:17 qw422016.N().S(` `) -//line views/nav.qtpl:18 +//line views/nav.qtpl:19 u := meta.U lc := meta.Lc backs := backlinks.BacklinksCount(h) -//line views/nav.qtpl:21 +//line views/nav.qtpl:22 qw422016.N().S(` `) -//line views/nav.qtpl:32 +//line views/nav.qtpl:33 } -//line views/nav.qtpl:32 -func writehyphaInfo(qq422016 qtio422016.Writer, meta Meta, h hyphae.Hypha) { -//line views/nav.qtpl:32 +//line views/nav.qtpl:33 +func writehyphaInfo(qq422016 qtio422016.Writer, meta viewutil.Meta, h hyphae.Hypha) { +//line views/nav.qtpl:33 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/nav.qtpl:32 +//line views/nav.qtpl:33 streamhyphaInfo(qw422016, meta, h) -//line views/nav.qtpl:32 +//line views/nav.qtpl:33 qt422016.ReleaseWriter(qw422016) -//line views/nav.qtpl:32 +//line views/nav.qtpl:33 } -//line views/nav.qtpl:32 -func hyphaInfo(meta Meta, h hyphae.Hypha) string { -//line views/nav.qtpl:32 +//line views/nav.qtpl:33 +func hyphaInfo(meta viewutil.Meta, h hyphae.Hypha) string { +//line views/nav.qtpl:33 qb422016 := qt422016.AcquireByteBuffer() -//line views/nav.qtpl:32 +//line views/nav.qtpl:33 writehyphaInfo(qb422016, meta, h) -//line views/nav.qtpl:32 +//line views/nav.qtpl:33 qs422016 := string(qb422016.B) -//line views/nav.qtpl:32 +//line views/nav.qtpl:33 qt422016.ReleaseByteBuffer(qb422016) -//line views/nav.qtpl:32 +//line views/nav.qtpl:33 return qs422016 -//line views/nav.qtpl:32 +//line views/nav.qtpl:33 } -//line views/nav.qtpl:34 +//line views/nav.qtpl:35 func streamsiblingHyphae(qw422016 *qt422016.Writer, siblings string, lc *l18n.Localizer) { -//line views/nav.qtpl:34 +//line views/nav.qtpl:35 qw422016.N().S(` `) -//line views/nav.qtpl:35 +//line views/nav.qtpl:36 if cfg.UseSiblingHyphaeSidebar { -//line views/nav.qtpl:35 +//line views/nav.qtpl:36 qw422016.N().S(` `) -//line views/nav.qtpl:40 +//line views/nav.qtpl:41 } -//line views/nav.qtpl:40 +//line views/nav.qtpl:41 qw422016.N().S(` `) -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 } -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 func writesiblingHyphae(qq422016 qtio422016.Writer, siblings string, lc *l18n.Localizer) { -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 streamsiblingHyphae(qw422016, siblings, lc) -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 qt422016.ReleaseWriter(qw422016) -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 } -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 func siblingHyphae(siblings string, lc *l18n.Localizer) string { -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 qb422016 := qt422016.AcquireByteBuffer() -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 writesiblingHyphae(qb422016, siblings, lc) -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 qs422016 := string(qb422016.B) -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 qt422016.ReleaseByteBuffer(qb422016) -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 return qs422016 -//line views/nav.qtpl:41 +//line views/nav.qtpl:42 } -//line views/nav.qtpl:43 +//line views/nav.qtpl:44 func StreamSubhyphae(qw422016 *qt422016.Writer, subhyphae string, lc *l18n.Localizer) { -//line views/nav.qtpl:43 +//line views/nav.qtpl:44 qw422016.N().S(` `) -//line views/nav.qtpl:44 +//line views/nav.qtpl:45 if strings.TrimSpace(subhyphae) != "" { -//line views/nav.qtpl:44 +//line views/nav.qtpl:45 qw422016.N().S(`

    `) -//line views/nav.qtpl:46 +//line views/nav.qtpl:47 qw422016.E().S(lc.Get("ui.subhyphae")) -//line views/nav.qtpl:46 +//line views/nav.qtpl:47 qw422016.N().S(`

    `) -//line views/nav.qtpl:53 +//line views/nav.qtpl:54 } -//line views/nav.qtpl:53 +//line views/nav.qtpl:54 qw422016.N().S(` `) -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 } -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 func WriteSubhyphae(qq422016 qtio422016.Writer, subhyphae string, lc *l18n.Localizer) { -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 StreamSubhyphae(qw422016, subhyphae, lc) -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 qt422016.ReleaseWriter(qw422016) -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 } -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 func Subhyphae(subhyphae string, lc *l18n.Localizer) string { -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 qb422016 := qt422016.AcquireByteBuffer() -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 WriteSubhyphae(qb422016, subhyphae, lc) -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 qs422016 := string(qb422016.B) -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 qt422016.ReleaseByteBuffer(qb422016) -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 return qs422016 -//line views/nav.qtpl:54 +//line views/nav.qtpl:55 } diff --git a/views/readers.qtpl b/views/readers.qtpl index 116f0e9..4eb397d 100644 --- a/views/readers.qtpl +++ b/views/readers.qtpl @@ -10,6 +10,7 @@ {% import "github.com/bouncepaw/mycorrhiza/tree" %} {% import "github.com/bouncepaw/mycorrhiza/user" %} {% import "github.com/bouncepaw/mycorrhiza/util" %} +{% import "github.com/bouncepaw/mycorrhiza/viewutil" %} {% func MediaMenu(rq *http.Request, h hyphae.Hypha, u *user.User) %} {% code @@ -85,7 +86,7 @@ If `contents` == "", a helpful message is shown instead. If you rename .prevnext, change the docs too. -{% func Hypha(meta Meta, h hyphae.Hypha, contents string) %} +{% func Hypha(meta viewutil.Meta, h hyphae.Hypha, contents string) %} {% code siblings, subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName()) lc := meta.Lc diff --git a/views/readers.qtpl.go b/views/readers.qtpl.go index 06ffd59..90e6540 100644 --- a/views/readers.qtpl.go +++ b/views/readers.qtpl.go @@ -37,599 +37,602 @@ import "github.com/bouncepaw/mycorrhiza/user" //line views/readers.qtpl:12 import "github.com/bouncepaw/mycorrhiza/util" -//line views/readers.qtpl:14 +//line views/readers.qtpl:13 +import "github.com/bouncepaw/mycorrhiza/viewutil" + +//line views/readers.qtpl:15 import ( qtio422016 "io" qt422016 "github.com/valyala/quicktemplate" ) -//line views/readers.qtpl:14 +//line views/readers.qtpl:15 var ( _ = qtio422016.Copy _ = qt422016.AcquireByteBuffer ) -//line views/readers.qtpl:14 +//line views/readers.qtpl:15 func StreamMediaMenu(qw422016 *qt422016.Writer, rq *http.Request, h hyphae.Hypha, u *user.User) { -//line views/readers.qtpl:14 +//line views/readers.qtpl:15 qw422016.N().S(` `) -//line views/readers.qtpl:16 +//line views/readers.qtpl:17 lc := l18n.FromRequest(rq) -//line views/readers.qtpl:17 +//line views/readers.qtpl:18 qw422016.N().S(`

    `) -//line views/readers.qtpl:20 +//line views/readers.qtpl:21 qw422016.N().S(lc.Get("ui.media_title", &l18n.Replacements{"name": beautifulLink(h.CanonicalName())})) -//line views/readers.qtpl:20 +//line views/readers.qtpl:21 qw422016.N().S(`

    `) -//line views/readers.qtpl:21 +//line views/readers.qtpl:22 switch h.(type) { -//line views/readers.qtpl:22 +//line views/readers.qtpl:23 case *hyphae.MediaHypha: -//line views/readers.qtpl:22 +//line views/readers.qtpl:23 qw422016.N().S(`

    `) -//line views/readers.qtpl:23 +//line views/readers.qtpl:24 qw422016.E().S(lc.Get("ui.media_tip")) -//line views/readers.qtpl:23 +//line views/readers.qtpl:24 qw422016.N().S(` `) -//line views/readers.qtpl:23 +//line views/readers.qtpl:24 qw422016.E().S(lc.Get("ui.media_what_is")) -//line views/readers.qtpl:23 +//line views/readers.qtpl:24 qw422016.N().S(`

    `) -//line views/readers.qtpl:24 +//line views/readers.qtpl:25 default: -//line views/readers.qtpl:24 +//line views/readers.qtpl:25 qw422016.N().S(`

    `) -//line views/readers.qtpl:25 +//line views/readers.qtpl:26 qw422016.E().S(lc.Get("ui.media_empty")) -//line views/readers.qtpl:25 +//line views/readers.qtpl:26 qw422016.N().S(` `) -//line views/readers.qtpl:25 +//line views/readers.qtpl:26 qw422016.E().S(lc.Get("ui.media_what_is")) -//line views/readers.qtpl:25 +//line views/readers.qtpl:26 qw422016.N().S(`

    `) -//line views/readers.qtpl:26 +//line views/readers.qtpl:27 } -//line views/readers.qtpl:26 +//line views/readers.qtpl:27 qw422016.N().S(`
    `) -//line views/readers.qtpl:29 +//line views/readers.qtpl:30 switch h := h.(type) { -//line views/readers.qtpl:30 +//line views/readers.qtpl:31 case *hyphae.MediaHypha: -//line views/readers.qtpl:30 +//line views/readers.qtpl:31 qw422016.N().S(` `) -//line views/readers.qtpl:32 +//line views/readers.qtpl:33 mime := mimetype.FromExtension(path.Ext(h.MediaFilePath())) fileinfo, err := os.Stat(h.MediaFilePath()) -//line views/readers.qtpl:33 +//line views/readers.qtpl:34 qw422016.N().S(` `) -//line views/readers.qtpl:34 +//line views/readers.qtpl:35 if err == nil { -//line views/readers.qtpl:34 +//line views/readers.qtpl:35 qw422016.N().S(`
    `) -//line views/readers.qtpl:36 +//line views/readers.qtpl:37 qw422016.E().S(lc.Get("ui.media_stat")) -//line views/readers.qtpl:36 +//line views/readers.qtpl:37 qw422016.N().S(`

    `) -//line views/readers.qtpl:38 +//line views/readers.qtpl:39 qw422016.E().S(lc.Get("ui.media_stat_mime")) -//line views/readers.qtpl:38 +//line views/readers.qtpl:39 qw422016.N().S(` `) -//line views/readers.qtpl:38 +//line views/readers.qtpl:39 qw422016.E().S(mime) -//line views/readers.qtpl:38 +//line views/readers.qtpl:39 qw422016.N().S(`

    `) -//line views/readers.qtpl:40 +//line views/readers.qtpl:41 } -//line views/readers.qtpl:40 +//line views/readers.qtpl:41 qw422016.N().S(` `) -//line views/readers.qtpl:42 +//line views/readers.qtpl:43 if strings.HasPrefix(mime, "image/") { -//line views/readers.qtpl:42 +//line views/readers.qtpl:43 qw422016.N().S(`
    `) -//line views/readers.qtpl:44 +//line views/readers.qtpl:45 qw422016.E().S(lc.Get("ui.media_include")) -//line views/readers.qtpl:44 +//line views/readers.qtpl:45 qw422016.N().S(`
    img { `)
    -//line views/readers.qtpl:46
    +//line views/readers.qtpl:47
     			qw422016.E().S(h.CanonicalName())
    -//line views/readers.qtpl:46
    +//line views/readers.qtpl:47
     			qw422016.N().S(` }
    `) -//line views/readers.qtpl:48 +//line views/readers.qtpl:49 } -//line views/readers.qtpl:48 +//line views/readers.qtpl:49 qw422016.N().S(` `) -//line views/readers.qtpl:49 +//line views/readers.qtpl:50 } -//line views/readers.qtpl:49 +//line views/readers.qtpl:50 qw422016.N().S(` `) -//line views/readers.qtpl:51 +//line views/readers.qtpl:52 if u.CanProceed("upload-binary") { -//line views/readers.qtpl:51 +//line views/readers.qtpl:52 qw422016.N().S(` `) -//line views/readers.qtpl:64 +//line views/readers.qtpl:65 } -//line views/readers.qtpl:64 +//line views/readers.qtpl:65 qw422016.N().S(` `) -//line views/readers.qtpl:67 +//line views/readers.qtpl:68 switch h := h.(type) { -//line views/readers.qtpl:68 +//line views/readers.qtpl:69 case *hyphae.MediaHypha: -//line views/readers.qtpl:68 +//line views/readers.qtpl:69 qw422016.N().S(` `) -//line views/readers.qtpl:69 +//line views/readers.qtpl:70 if u.CanProceed("remove-media") { -//line views/readers.qtpl:69 +//line views/readers.qtpl:70 qw422016.N().S(` `) -//line views/readers.qtpl:77 +//line views/readers.qtpl:78 } -//line views/readers.qtpl:77 +//line views/readers.qtpl:78 qw422016.N().S(` `) -//line views/readers.qtpl:78 +//line views/readers.qtpl:79 } -//line views/readers.qtpl:78 +//line views/readers.qtpl:79 qw422016.N().S(`
    `) -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 } -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 func WriteMediaMenu(qq422016 qtio422016.Writer, rq *http.Request, h hyphae.Hypha, u *user.User) { -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 StreamMediaMenu(qw422016, rq, h, u) -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 qt422016.ReleaseWriter(qw422016) -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 } -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 func MediaMenu(rq *http.Request, h hyphae.Hypha, u *user.User) string { -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 qb422016 := qt422016.AcquireByteBuffer() -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 WriteMediaMenu(qb422016, rq, h, u) -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 qs422016 := string(qb422016.B) -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 qt422016.ReleaseByteBuffer(qb422016) -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 return qs422016 -//line views/readers.qtpl:83 +//line views/readers.qtpl:84 } // If `contents` == "", a helpful message is shown instead. // // If you rename .prevnext, change the docs too. -//line views/readers.qtpl:88 -func StreamHypha(qw422016 *qt422016.Writer, meta Meta, h hyphae.Hypha, contents string) { -//line views/readers.qtpl:88 +//line views/readers.qtpl:89 +func StreamHypha(qw422016 *qt422016.Writer, meta viewutil.Meta, h hyphae.Hypha, contents string) { +//line views/readers.qtpl:89 qw422016.N().S(` `) -//line views/readers.qtpl:90 +//line views/readers.qtpl:91 siblings, subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName()) lc := meta.Lc -//line views/readers.qtpl:92 +//line views/readers.qtpl:93 qw422016.N().S(`
    `) -//line views/readers.qtpl:96 +//line views/readers.qtpl:97 if meta.U.CanProceed("edit") { -//line views/readers.qtpl:96 +//line views/readers.qtpl:97 qw422016.N().S(` `) -//line views/readers.qtpl:100 +//line views/readers.qtpl:101 } -//line views/readers.qtpl:100 +//line views/readers.qtpl:101 qw422016.N().S(` `) -//line views/readers.qtpl:102 +//line views/readers.qtpl:103 if cfg.UseAuth && util.IsProfileName(h.CanonicalName()) && meta.U.Name == strings.TrimPrefix(h.CanonicalName(), cfg.UserHypha+"/") { -//line views/readers.qtpl:102 +//line views/readers.qtpl:103 qw422016.N().S(` `) -//line views/readers.qtpl:106 +//line views/readers.qtpl:107 if meta.U.Group == "admin" { -//line views/readers.qtpl:106 +//line views/readers.qtpl:107 qw422016.N().S(` `) -//line views/readers.qtpl:110 +//line views/readers.qtpl:111 } -//line views/readers.qtpl:110 +//line views/readers.qtpl:111 qw422016.N().S(` `) -//line views/readers.qtpl:111 +//line views/readers.qtpl:112 } -//line views/readers.qtpl:111 +//line views/readers.qtpl:112 qw422016.N().S(` `) -//line views/readers.qtpl:113 +//line views/readers.qtpl:114 qw422016.N().S(NaviTitle(h)) -//line views/readers.qtpl:113 +//line views/readers.qtpl:114 qw422016.N().S(` `) -//line views/readers.qtpl:114 +//line views/readers.qtpl:115 switch h.(type) { -//line views/readers.qtpl:115 +//line views/readers.qtpl:116 case *hyphae.EmptyHypha: -//line views/readers.qtpl:115 +//line views/readers.qtpl:116 qw422016.N().S(` `) -//line views/readers.qtpl:116 +//line views/readers.qtpl:117 streamnonExistentHyphaNotice(qw422016, h, meta.U, meta.Lc) -//line views/readers.qtpl:116 +//line views/readers.qtpl:117 qw422016.N().S(` `) -//line views/readers.qtpl:117 +//line views/readers.qtpl:118 default: -//line views/readers.qtpl:117 +//line views/readers.qtpl:118 qw422016.N().S(` `) -//line views/readers.qtpl:118 +//line views/readers.qtpl:119 qw422016.N().S(contents) -//line views/readers.qtpl:118 +//line views/readers.qtpl:119 qw422016.N().S(` `) -//line views/readers.qtpl:119 +//line views/readers.qtpl:120 } -//line views/readers.qtpl:119 +//line views/readers.qtpl:120 qw422016.N().S(`
    `) -//line views/readers.qtpl:122 +//line views/readers.qtpl:123 if prevHyphaName != "" { -//line views/readers.qtpl:122 +//line views/readers.qtpl:123 qw422016.N().S(` `) -//line views/readers.qtpl:124 +//line views/readers.qtpl:125 } -//line views/readers.qtpl:124 +//line views/readers.qtpl:125 qw422016.N().S(` `) -//line views/readers.qtpl:125 +//line views/readers.qtpl:126 if nextHyphaName != "" { -//line views/readers.qtpl:125 +//line views/readers.qtpl:126 qw422016.N().S(` `) -//line views/readers.qtpl:127 +//line views/readers.qtpl:128 } -//line views/readers.qtpl:127 +//line views/readers.qtpl:128 qw422016.N().S(`
    `) -//line views/readers.qtpl:129 +//line views/readers.qtpl:130 StreamSubhyphae(qw422016, subhyphae, meta.Lc) -//line views/readers.qtpl:129 +//line views/readers.qtpl:130 qw422016.N().S(`
    `) -//line views/readers.qtpl:131 +//line views/readers.qtpl:132 streamhyphaInfo(qw422016, meta, h) -//line views/readers.qtpl:131 +//line views/readers.qtpl:132 qw422016.N().S(`
    `) -//line views/readers.qtpl:134 +//line views/readers.qtpl:135 qw422016.N().S(categoryCard(meta, h.CanonicalName())) -//line views/readers.qtpl:134 +//line views/readers.qtpl:135 qw422016.N().S(` `) -//line views/readers.qtpl:135 +//line views/readers.qtpl:136 streamsiblingHyphae(qw422016, siblings, meta.Lc) -//line views/readers.qtpl:135 +//line views/readers.qtpl:136 qw422016.N().S(`
    `) -//line views/readers.qtpl:137 +//line views/readers.qtpl:138 streamviewScripts(qw422016) -//line views/readers.qtpl:137 +//line views/readers.qtpl:138 qw422016.N().S(` `) -//line views/readers.qtpl:138 +//line views/readers.qtpl:139 } -//line views/readers.qtpl:138 -func WriteHypha(qq422016 qtio422016.Writer, meta Meta, h hyphae.Hypha, contents string) { -//line views/readers.qtpl:138 +//line views/readers.qtpl:139 +func WriteHypha(qq422016 qtio422016.Writer, meta viewutil.Meta, h hyphae.Hypha, contents string) { +//line views/readers.qtpl:139 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/readers.qtpl:138 +//line views/readers.qtpl:139 StreamHypha(qw422016, meta, h, contents) -//line views/readers.qtpl:138 +//line views/readers.qtpl:139 qt422016.ReleaseWriter(qw422016) -//line views/readers.qtpl:138 +//line views/readers.qtpl:139 } -//line views/readers.qtpl:138 -func Hypha(meta Meta, h hyphae.Hypha, contents string) string { -//line views/readers.qtpl:138 +//line views/readers.qtpl:139 +func Hypha(meta viewutil.Meta, h hyphae.Hypha, contents string) string { +//line views/readers.qtpl:139 qb422016 := qt422016.AcquireByteBuffer() -//line views/readers.qtpl:138 +//line views/readers.qtpl:139 WriteHypha(qb422016, meta, h, contents) -//line views/readers.qtpl:138 +//line views/readers.qtpl:139 qs422016 := string(qb422016.B) -//line views/readers.qtpl:138 +//line views/readers.qtpl:139 qt422016.ReleaseByteBuffer(qb422016) -//line views/readers.qtpl:138 +//line views/readers.qtpl:139 return qs422016 -//line views/readers.qtpl:138 +//line views/readers.qtpl:139 } -//line views/readers.qtpl:140 +//line views/readers.qtpl:141 func StreamRevision(qw422016 *qt422016.Writer, rq *http.Request, lc *l18n.Localizer, h hyphae.Hypha, contents, revHash string) { -//line views/readers.qtpl:140 +//line views/readers.qtpl:141 qw422016.N().S(`

    `) -//line views/readers.qtpl:144 +//line views/readers.qtpl:145 qw422016.E().S(lc.Get("ui.revision_warning")) -//line views/readers.qtpl:144 +//line views/readers.qtpl:145 qw422016.N().S(` `) -//line views/readers.qtpl:144 +//line views/readers.qtpl:145 qw422016.E().S(lc.Get("ui.revision_link")) -//line views/readers.qtpl:144 +//line views/readers.qtpl:145 qw422016.N().S(`

    `) -//line views/readers.qtpl:145 +//line views/readers.qtpl:146 qw422016.N().S(NaviTitle(h)) -//line views/readers.qtpl:145 +//line views/readers.qtpl:146 qw422016.N().S(` `) -//line views/readers.qtpl:146 +//line views/readers.qtpl:147 qw422016.N().S(contents) -//line views/readers.qtpl:146 +//line views/readers.qtpl:147 qw422016.N().S(`
    `) -//line views/readers.qtpl:150 +//line views/readers.qtpl:151 streamviewScripts(qw422016) -//line views/readers.qtpl:150 +//line views/readers.qtpl:151 qw422016.N().S(` `) -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 } -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 func WriteRevision(qq422016 qtio422016.Writer, rq *http.Request, lc *l18n.Localizer, h hyphae.Hypha, contents, revHash string) { -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 StreamRevision(qw422016, rq, lc, h, contents, revHash) -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 qt422016.ReleaseWriter(qw422016) -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 } -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 func Revision(rq *http.Request, lc *l18n.Localizer, h hyphae.Hypha, contents, revHash string) string { -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 qb422016 := qt422016.AcquireByteBuffer() -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 WriteRevision(qb422016, rq, lc, h, contents, revHash) -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 qs422016 := string(qb422016.B) -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 qt422016.ReleaseByteBuffer(qb422016) -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 return qs422016 -//line views/readers.qtpl:151 +//line views/readers.qtpl:152 } -//line views/readers.qtpl:153 +//line views/readers.qtpl:154 func streamviewScripts(qw422016 *qt422016.Writer) { -//line views/readers.qtpl:153 +//line views/readers.qtpl:154 qw422016.N().S(` `) -//line views/readers.qtpl:154 +//line views/readers.qtpl:155 for _, scriptPath := range cfg.ViewScripts { -//line views/readers.qtpl:154 +//line views/readers.qtpl:155 qw422016.N().S(` `) -//line views/readers.qtpl:156 +//line views/readers.qtpl:157 } -//line views/readers.qtpl:156 +//line views/readers.qtpl:157 qw422016.N().S(` `) -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 } -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 func writeviewScripts(qq422016 qtio422016.Writer) { -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 streamviewScripts(qw422016) -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 qt422016.ReleaseWriter(qw422016) -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 } -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 func viewScripts() string { -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 qb422016 := qt422016.AcquireByteBuffer() -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 writeviewScripts(qb422016) -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 qs422016 := string(qb422016.B) -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 qt422016.ReleaseByteBuffer(qb422016) -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 return qs422016 -//line views/readers.qtpl:157 +//line views/readers.qtpl:158 } diff --git a/viewutil/base.html b/viewutil/base.html new file mode 100644 index 0000000..8bbdf7c --- /dev/null +++ b/viewutil/base.html @@ -0,0 +1,83 @@ +{{define "base"}} + + + + + + {{.Title}} + + + + {{range .HeadElements}}{{.}}{{end}} + + +
    + +
    +{{block "body" .}}{{end}} + +{{range .CommonScripts}}{{.}}{{end}} + + + + +{{end}} \ No newline at end of file diff --git a/viewutil/meta.go b/viewutil/meta.go new file mode 100644 index 0000000..c51db6e --- /dev/null +++ b/viewutil/meta.go @@ -0,0 +1,28 @@ +package viewutil + +import ( + "github.com/bouncepaw/mycorrhiza/l18n" + "github.com/bouncepaw/mycorrhiza/user" + "io" + "net/http" +) + +// Meta is a bundle of common stuffs used by views, templates. +type Meta struct { + Lc *l18n.Localizer + U *user.User + W io.Writer +} + +// MetaFrom makes a Meta from the given data. You are meant to further modify it. +func MetaFrom(w http.ResponseWriter, rq *http.Request) Meta { + return Meta{ + Lc: l18n.FromRequest(rq), + U: user.FromRequest(rq), + W: w, + } +} + +func (m *Meta) Locale() string { + return m.Lc.Locale +} diff --git a/viewutil/viewutil.go b/viewutil/viewutil.go new file mode 100644 index 0000000..f023101 --- /dev/null +++ b/viewutil/viewutil.go @@ -0,0 +1,85 @@ +// Package viewutil provides utilities and common templates for views across all packages. +package viewutil + +import ( + "embed" + "fmt" + "github.com/bouncepaw/mycorrhiza/cfg" + "github.com/bouncepaw/mycorrhiza/l18n" + "github.com/bouncepaw/mycorrhiza/user" + "html/template" + "log" + "strings" +) + +var ( + //go:embed viewutil.go + fs embed.FS + BaseEn *template.Template + BaseRu *template.Template + m = template.Must +) + +const ruText = ` +{{define "search by title"}}Поиск по названию{{end}} +{{define "close this dialog"}}Закрыть этот диалог{{end}} +{{define "login"}}Войти{{end}} +{{define "Register"}}Регистрация{{end}} +` + +func Init() { + dataText := fmt.Sprintf(` +{{define "wiki name"}}%s{{end}} +`, cfg.WikiName) + BaseEn = m(m(template.ParseFS(fs, "viewutil.go")).Parse(dataText)) + if !cfg.UseAuth { + m(BaseEn.Parse(`{{define "auth"}}{{end}}`)) + } + if !cfg.AllowRegistration { + m(BaseEn.Parse(`{{define "registration"}}{{end}}`)) + } + BaseRu = m(m(BaseEn.Clone()).Parse(ruText)) +} + +// TODO: get rid of this +func localizedBaseWithWeirdBody(meta Meta) *template.Template { + t := func() *template.Template { + if meta.Locale() == "ru" { + return BaseRu + } + return BaseEn + }() + return m(m(t.Clone()).Parse(`{{define "body"}}.Body{{end}}`)) +} + +type baseData struct { + Meta Meta + Title string + HeadElements []string + HeaderLinks []cfg.HeaderLink + CommonScripts []string + Body string // TODO: remove +} + +// Base is a temporary wrapper around BaseEn and BaseRu, meant to facilitate the migration from qtpl. +func Base(title, body string, lc *l18n.Localizer, u *user.User, headElements ...string) string { + var w strings.Builder + meta := Meta{ + Lc: lc, + U: u, + W: &w, + } + t := localizedBaseWithWeirdBody(meta) + err := t.Execute(&w, baseData{ + Meta: meta, + Title: title, + HeadElements: headElements, + HeaderLinks: cfg.HeaderLinks, + CommonScripts: cfg.CommonScripts, + Body: body, + }) + if err != nil { + log.Println(err) + } + return w.String() +} diff --git a/web/admin.go b/web/admin.go index a463f9a..2302d85 100644 --- a/web/admin.go +++ b/web/admin.go @@ -2,6 +2,7 @@ package web import ( "fmt" + "github.com/bouncepaw/mycorrhiza/viewutil" "io" "log" "mime" @@ -35,7 +36,7 @@ func initAdmin(r *mux.Router) { func handlerAdmin(w http.ResponseWriter, rq *http.Request) { w.Header().Set("Content-Type", "text/html;charset=utf-8") w.WriteHeader(http.StatusOK) - views.AdminPanel(views.MetaFrom(w, rq)) + views.AdminPanel(viewutil.MetaFrom(w, rq)) } // handlerAdminShutdown kills the wiki. diff --git a/web/categories.go b/web/categories.go index fc42444..aa38545 100644 --- a/web/categories.go +++ b/web/categories.go @@ -5,6 +5,7 @@ import ( "github.com/bouncepaw/mycorrhiza/user" "github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/views" + "github.com/bouncepaw/mycorrhiza/viewutil" "github.com/gorilla/mux" "io" "log" @@ -21,7 +22,7 @@ func initCategories(r *mux.Router) { func handlerListCategory(w http.ResponseWriter, rq *http.Request) { log.Println("Viewing list of categories") - views.CategoryList(views.MetaFrom(w, rq)) + views.CategoryList(viewutil.MetaFrom(w, rq)) } func handlerCategory(w http.ResponseWriter, rq *http.Request) { @@ -32,7 +33,7 @@ func handlerCategory(w http.ResponseWriter, rq *http.Request) { return } log.Println("Viewing category", catName) - views.CategoryPage(views.MetaFrom(w, rq), catName) + views.CategoryPage(viewutil.MetaFrom(w, rq), catName) } func handlerRemoveFromCategory(w http.ResponseWriter, rq *http.Request) { diff --git a/web/readers.go b/web/readers.go index 051279d..de44839 100644 --- a/web/readers.go +++ b/web/readers.go @@ -3,6 +3,7 @@ package web import ( "encoding/hex" "fmt" + "github.com/bouncepaw/mycorrhiza/viewutil" "io" "log" "net/http" @@ -209,7 +210,7 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) { util.HTTP404Page(w, views.Base( util.BeautifulName(hyphaName), - views.Hypha(views.MetaFrom(w, rq), h, contents), + views.Hypha(viewutil.MetaFrom(w, rq), h, contents), lc, u, openGraph)) @@ -231,7 +232,7 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) { util.HTTP200Page(w, views.Base( util.BeautifulName(hyphaName), - views.Hypha(views.MetaFrom(w, rq), h, contents), + views.Hypha(viewutil.MetaFrom(w, rq), h, contents), lc, u, openGraph))