1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2025-08-06 22:04:11 +00:00

Implement viewutil.Base

This commit is contained in:
Timur Ismagilov 2022-03-29 23:59:36 +03:00
parent db943a97cb
commit a8b3e3d43a
14 changed files with 557 additions and 367 deletions

View File

@ -7,6 +7,7 @@ package main
import ( import (
"github.com/bouncepaw/mycorrhiza/hyphae/categories" "github.com/bouncepaw/mycorrhiza/hyphae/categories"
"github.com/bouncepaw/mycorrhiza/migration" "github.com/bouncepaw/mycorrhiza/migration"
"github.com/bouncepaw/mycorrhiza/viewutil"
"log" "log"
"os" "os"
@ -41,6 +42,7 @@ func main() {
log.Println("Using Git storage at", files.HyphaeDir()) log.Println("Using Git storage at", files.HyphaeDir())
// Init the subsystems: // Init the subsystems:
viewutil.Init()
hyphae.Index(files.HyphaeDir()) hyphae.Index(files.HyphaeDir())
backlinks.IndexBacklinks() backlinks.IndexBacklinks()
go backlinks.RunBacklinksConveyor() go backlinks.RunBacklinksConveyor()

View File

@ -2,6 +2,7 @@ package views
import ( import (
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/viewutil"
"html/template" "html/template"
"io" "io"
"log" "log"
@ -25,7 +26,7 @@ var (
adminTemplatesRu *template.Template adminTemplatesRu *template.Template
) )
func localizedAdminTemplates(meta Meta) *template.Template { func localizedAdminTemplates(meta viewutil.Meta) *template.Template {
if meta.Lc.Locale == "ru" { if meta.Lc.Locale == "ru" {
return adminTemplatesRu return adminTemplatesRu
} }
@ -59,7 +60,7 @@ func init() {
template.Must(adminTemplatesEn.Clone()).Parse(adminTranslationRu)) template.Must(adminTemplatesEn.Clone()).Parse(adminTranslationRu))
} }
func AdminPanel(meta Meta) { func AdminPanel(meta viewutil.Meta) {
var buf strings.Builder var buf strings.Builder
err := localizedAdminTemplates(meta).ExecuteTemplate(&buf, "panel", nil) err := localizedAdminTemplates(meta).ExecuteTemplate(&buf, "panel", nil)
if err != nil { if err != nil {

View File

@ -2,28 +2,7 @@ package views
import ( import (
"embed" "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 //go:embed *.html
var fs embed.FS var fs embed.FS

View File

@ -3,6 +3,7 @@ package views
import ( import (
"github.com/bouncepaw/mycorrhiza/hyphae/categories" "github.com/bouncepaw/mycorrhiza/hyphae/categories"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/viewutil"
"html/template" "html/template"
"io" "io"
"log" "log"
@ -39,14 +40,14 @@ func init() {
categoryTemplatesRu = template.Must(template.Must(categoryTemplatesEn.Clone()).Parse(categoriesRu)) 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" { if meta.Lc.Locale == "ru" {
return categoryTemplatesRu return categoryTemplatesRu
} }
return categoryTemplatesEn 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 buf strings.Builder
var err error var err error
if len(datum) == 1 { if len(datum) == 1 {
@ -61,7 +62,7 @@ func localizedCatTemplateAsString(meta Meta, name string, datum ...interface{})
return buf.String() return buf.String()
} }
func categoryCard(meta Meta, hyphaName string) string { func categoryCard(meta viewutil.Meta, hyphaName string) string {
var buf strings.Builder var buf strings.Builder
err := localizedCatTemplates(meta).ExecuteTemplate(&buf, "category card", struct { err := localizedCatTemplates(meta).ExecuteTemplate(&buf, "category card", struct {
HyphaName string HyphaName string
@ -78,7 +79,7 @@ func categoryCard(meta Meta, hyphaName string) string {
return buf.String() return buf.String()
} }
func CategoryPage(meta Meta, catName string) { func CategoryPage(meta viewutil.Meta, catName string) {
var buf strings.Builder var buf strings.Builder
err := localizedCatTemplates(meta).ExecuteTemplate(&buf, "category page", struct { err := localizedCatTemplates(meta).ExecuteTemplate(&buf, "category page", struct {
CatName string 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 var buf strings.Builder
err := localizedCatTemplates(meta).ExecuteTemplate(&buf, "category list", struct { err := localizedCatTemplates(meta).ExecuteTemplate(&buf, "category list", struct {
Categories []string Categories []string

View File

@ -4,6 +4,7 @@
{% import "github.com/bouncepaw/mycorrhiza/l18n" %} {% import "github.com/bouncepaw/mycorrhiza/l18n" %}
{% import "github.com/bouncepaw/mycorrhiza/user" %} {% import "github.com/bouncepaw/mycorrhiza/user" %}
{% import "github.com/bouncepaw/mycorrhiza/hyphae" %} {% import "github.com/bouncepaw/mycorrhiza/hyphae" %}
{% import "github.com/bouncepaw/mycorrhiza/viewutil" %}
{% func hyphaInfoEntry(h hyphae.Hypha, u *user.User, action, displayText string) %} {% func hyphaInfoEntry(h hyphae.Hypha, u *user.User, action, displayText string) %}
{% if u.CanProceed(action) %} {% if u.CanProceed(action) %}
@ -13,7 +14,7 @@
{% endif %} {% endif %}
{% endfunc %} {% endfunc %}
{% func hyphaInfo(meta Meta, h hyphae.Hypha) %} {% func hyphaInfo(meta viewutil.Meta, h hyphae.Hypha) %}
{% code {% code
u := meta.U u := meta.U
lc := meta.Lc lc := meta.Lc

View File

@ -22,270 +22,273 @@ import "github.com/bouncepaw/mycorrhiza/user"
//line views/nav.qtpl:6 //line views/nav.qtpl:6
import "github.com/bouncepaw/mycorrhiza/hyphae" 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 ( import (
qtio422016 "io" qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate" qt422016 "github.com/valyala/quicktemplate"
) )
//line views/nav.qtpl:8 //line views/nav.qtpl:9
var ( var (
_ = qtio422016.Copy _ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer _ = 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) { 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(` qw422016.N().S(`
`) `)
//line views/nav.qtpl:9 //line views/nav.qtpl:10
if u.CanProceed(action) { if u.CanProceed(action) {
//line views/nav.qtpl:9 //line views/nav.qtpl:10
qw422016.N().S(` qw422016.N().S(`
<li class="hypha-info__entry hypha-info__entry_`) <li class="hypha-info__entry hypha-info__entry_`)
//line views/nav.qtpl:10 //line views/nav.qtpl:11
qw422016.E().S(action) qw422016.E().S(action)
//line views/nav.qtpl:10 //line views/nav.qtpl:11
qw422016.N().S(`"> qw422016.N().S(`">
<a class="hypha-info__link" href="/`) <a class="hypha-info__link" href="/`)
//line views/nav.qtpl:11 //line views/nav.qtpl:12
qw422016.E().S(action) qw422016.E().S(action)
//line views/nav.qtpl:11 //line views/nav.qtpl:12
qw422016.N().S(`/`) qw422016.N().S(`/`)
//line views/nav.qtpl:11 //line views/nav.qtpl:12
qw422016.E().S(h.CanonicalName()) qw422016.E().S(h.CanonicalName())
//line views/nav.qtpl:11 //line views/nav.qtpl:12
qw422016.N().S(`">`) qw422016.N().S(`">`)
//line views/nav.qtpl:11 //line views/nav.qtpl:12
qw422016.E().S(displayText) qw422016.E().S(displayText)
//line views/nav.qtpl:11 //line views/nav.qtpl:12
qw422016.N().S(`</a> qw422016.N().S(`</a>
</li> </li>
`) `)
//line views/nav.qtpl:13 //line views/nav.qtpl:14
} }
//line views/nav.qtpl:13 //line views/nav.qtpl:14
qw422016.N().S(` 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) { 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) qw422016 := qt422016.AcquireWriter(qq422016)
//line views/nav.qtpl:14 //line views/nav.qtpl:15
streamhyphaInfoEntry(qw422016, h, u, action, displayText) streamhyphaInfoEntry(qw422016, h, u, action, displayText)
//line views/nav.qtpl:14 //line views/nav.qtpl:15
qt422016.ReleaseWriter(qw422016) 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 { 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() qb422016 := qt422016.AcquireByteBuffer()
//line views/nav.qtpl:14 //line views/nav.qtpl:15
writehyphaInfoEntry(qb422016, h, u, action, displayText) writehyphaInfoEntry(qb422016, h, u, action, displayText)
//line views/nav.qtpl:14 //line views/nav.qtpl:15
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line views/nav.qtpl:14 //line views/nav.qtpl:15
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line views/nav.qtpl:14 //line views/nav.qtpl:15
return qs422016 return qs422016
//line views/nav.qtpl:14 //line views/nav.qtpl:15
} }
//line views/nav.qtpl:16 //line views/nav.qtpl:17
func streamhyphaInfo(qw422016 *qt422016.Writer, meta Meta, h hyphae.Hypha) { func streamhyphaInfo(qw422016 *qt422016.Writer, meta viewutil.Meta, h hyphae.Hypha) {
//line views/nav.qtpl:16 //line views/nav.qtpl:17
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/nav.qtpl:18 //line views/nav.qtpl:19
u := meta.U u := meta.U
lc := meta.Lc lc := meta.Lc
backs := backlinks.BacklinksCount(h) backs := backlinks.BacklinksCount(h)
//line views/nav.qtpl:21 //line views/nav.qtpl:22
qw422016.N().S(` qw422016.N().S(`
<nav class="hypha-info"> <nav class="hypha-info">
<ul class="hypha-info__list"> <ul class="hypha-info__list">
`) `)
//line views/nav.qtpl:24 //line views/nav.qtpl:25
streamhyphaInfoEntry(qw422016, h, u, "history", lc.Get("ui.history_link")) streamhyphaInfoEntry(qw422016, h, u, "history", lc.Get("ui.history_link"))
//line views/nav.qtpl:24 //line views/nav.qtpl:25
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/nav.qtpl:25 //line views/nav.qtpl:26
streamhyphaInfoEntry(qw422016, h, u, "rename", lc.Get("ui.rename_link")) streamhyphaInfoEntry(qw422016, h, u, "rename", lc.Get("ui.rename_link"))
//line views/nav.qtpl:25 //line views/nav.qtpl:26
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/nav.qtpl:26 //line views/nav.qtpl:27
streamhyphaInfoEntry(qw422016, h, u, "delete", lc.Get("ui.delete_link")) streamhyphaInfoEntry(qw422016, h, u, "delete", lc.Get("ui.delete_link"))
//line views/nav.qtpl:26 //line views/nav.qtpl:27
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/nav.qtpl:27 //line views/nav.qtpl:28
streamhyphaInfoEntry(qw422016, h, u, "text", lc.Get("ui.text_link")) streamhyphaInfoEntry(qw422016, h, u, "text", lc.Get("ui.text_link"))
//line views/nav.qtpl:27 //line views/nav.qtpl:28
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/nav.qtpl:28 //line views/nav.qtpl:29
streamhyphaInfoEntry(qw422016, h, u, "media", lc.Get("ui.media_link")) streamhyphaInfoEntry(qw422016, h, u, "media", lc.Get("ui.media_link"))
//line views/nav.qtpl:28 //line views/nav.qtpl:29
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/nav.qtpl:29 //line views/nav.qtpl:30
streamhyphaInfoEntry(qw422016, h, u, "backlinks", lc.GetPlural("ui.backlinks_link", backs)) streamhyphaInfoEntry(qw422016, h, u, "backlinks", lc.GetPlural("ui.backlinks_link", backs))
//line views/nav.qtpl:29 //line views/nav.qtpl:30
qw422016.N().S(` qw422016.N().S(`
</ul> </ul>
</nav> </nav>
`) `)
//line views/nav.qtpl:32 //line views/nav.qtpl:33
} }
//line views/nav.qtpl:32 //line views/nav.qtpl:33
func writehyphaInfo(qq422016 qtio422016.Writer, meta Meta, h hyphae.Hypha) { func writehyphaInfo(qq422016 qtio422016.Writer, meta viewutil.Meta, h hyphae.Hypha) {
//line views/nav.qtpl:32 //line views/nav.qtpl:33
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line views/nav.qtpl:32 //line views/nav.qtpl:33
streamhyphaInfo(qw422016, meta, h) streamhyphaInfo(qw422016, meta, h)
//line views/nav.qtpl:32 //line views/nav.qtpl:33
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line views/nav.qtpl:32 //line views/nav.qtpl:33
} }
//line views/nav.qtpl:32 //line views/nav.qtpl:33
func hyphaInfo(meta Meta, h hyphae.Hypha) string { func hyphaInfo(meta viewutil.Meta, h hyphae.Hypha) string {
//line views/nav.qtpl:32 //line views/nav.qtpl:33
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line views/nav.qtpl:32 //line views/nav.qtpl:33
writehyphaInfo(qb422016, meta, h) writehyphaInfo(qb422016, meta, h)
//line views/nav.qtpl:32 //line views/nav.qtpl:33
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line views/nav.qtpl:32 //line views/nav.qtpl:33
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line views/nav.qtpl:32 //line views/nav.qtpl:33
return qs422016 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) { func streamsiblingHyphae(qw422016 *qt422016.Writer, siblings string, lc *l18n.Localizer) {
//line views/nav.qtpl:34 //line views/nav.qtpl:35
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/nav.qtpl:35 //line views/nav.qtpl:36
if cfg.UseSiblingHyphaeSidebar { if cfg.UseSiblingHyphaeSidebar {
//line views/nav.qtpl:35 //line views/nav.qtpl:36
qw422016.N().S(` qw422016.N().S(`
<aside class="sibling-hyphae layout-card"> <aside class="sibling-hyphae layout-card">
<h2 class="sibling-hyphae__title layout-card__title">`) <h2 class="sibling-hyphae__title layout-card__title">`)
//line views/nav.qtpl:37 //line views/nav.qtpl:38
qw422016.E().S(lc.Get("ui.sibling_hyphae")) qw422016.E().S(lc.Get("ui.sibling_hyphae"))
//line views/nav.qtpl:37 //line views/nav.qtpl:38
qw422016.N().S(`</h2> qw422016.N().S(`</h2>
`) `)
//line views/nav.qtpl:38 //line views/nav.qtpl:39
qw422016.N().S(siblings) qw422016.N().S(siblings)
//line views/nav.qtpl:38 //line views/nav.qtpl:39
qw422016.N().S(` qw422016.N().S(`
</aside> </aside>
`) `)
//line views/nav.qtpl:40 //line views/nav.qtpl:41
} }
//line views/nav.qtpl:40 //line views/nav.qtpl:41
qw422016.N().S(` 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) { func writesiblingHyphae(qq422016 qtio422016.Writer, siblings string, lc *l18n.Localizer) {
//line views/nav.qtpl:41 //line views/nav.qtpl:42
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line views/nav.qtpl:41 //line views/nav.qtpl:42
streamsiblingHyphae(qw422016, siblings, lc) streamsiblingHyphae(qw422016, siblings, lc)
//line views/nav.qtpl:41 //line views/nav.qtpl:42
qt422016.ReleaseWriter(qw422016) 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 { func siblingHyphae(siblings string, lc *l18n.Localizer) string {
//line views/nav.qtpl:41 //line views/nav.qtpl:42
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line views/nav.qtpl:41 //line views/nav.qtpl:42
writesiblingHyphae(qb422016, siblings, lc) writesiblingHyphae(qb422016, siblings, lc)
//line views/nav.qtpl:41 //line views/nav.qtpl:42
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line views/nav.qtpl:41 //line views/nav.qtpl:42
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line views/nav.qtpl:41 //line views/nav.qtpl:42
return qs422016 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) { func StreamSubhyphae(qw422016 *qt422016.Writer, subhyphae string, lc *l18n.Localizer) {
//line views/nav.qtpl:43 //line views/nav.qtpl:44
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/nav.qtpl:44 //line views/nav.qtpl:45
if strings.TrimSpace(subhyphae) != "" { if strings.TrimSpace(subhyphae) != "" {
//line views/nav.qtpl:44 //line views/nav.qtpl:45
qw422016.N().S(` qw422016.N().S(`
<section class="subhyphae"> <section class="subhyphae">
<h2 class="subhyphae__title">`) <h2 class="subhyphae__title">`)
//line views/nav.qtpl:46 //line views/nav.qtpl:47
qw422016.E().S(lc.Get("ui.subhyphae")) qw422016.E().S(lc.Get("ui.subhyphae"))
//line views/nav.qtpl:46 //line views/nav.qtpl:47
qw422016.N().S(`</h2> qw422016.N().S(`</h2>
<nav class="subhyphae__nav"> <nav class="subhyphae__nav">
<ul class="subhyphae__list"> <ul class="subhyphae__list">
`) `)
//line views/nav.qtpl:49 //line views/nav.qtpl:50
qw422016.N().S(subhyphae) qw422016.N().S(subhyphae)
//line views/nav.qtpl:49 //line views/nav.qtpl:50
qw422016.N().S(` qw422016.N().S(`
</ul> </ul>
</nav> </nav>
</section> </section>
`) `)
//line views/nav.qtpl:53 //line views/nav.qtpl:54
} }
//line views/nav.qtpl:53 //line views/nav.qtpl:54
qw422016.N().S(` 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) { func WriteSubhyphae(qq422016 qtio422016.Writer, subhyphae string, lc *l18n.Localizer) {
//line views/nav.qtpl:54 //line views/nav.qtpl:55
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line views/nav.qtpl:54 //line views/nav.qtpl:55
StreamSubhyphae(qw422016, subhyphae, lc) StreamSubhyphae(qw422016, subhyphae, lc)
//line views/nav.qtpl:54 //line views/nav.qtpl:55
qt422016.ReleaseWriter(qw422016) 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 { func Subhyphae(subhyphae string, lc *l18n.Localizer) string {
//line views/nav.qtpl:54 //line views/nav.qtpl:55
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line views/nav.qtpl:54 //line views/nav.qtpl:55
WriteSubhyphae(qb422016, subhyphae, lc) WriteSubhyphae(qb422016, subhyphae, lc)
//line views/nav.qtpl:54 //line views/nav.qtpl:55
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line views/nav.qtpl:54 //line views/nav.qtpl:55
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line views/nav.qtpl:54 //line views/nav.qtpl:55
return qs422016 return qs422016
//line views/nav.qtpl:54 //line views/nav.qtpl:55
} }

View File

@ -10,6 +10,7 @@
{% import "github.com/bouncepaw/mycorrhiza/tree" %} {% import "github.com/bouncepaw/mycorrhiza/tree" %}
{% import "github.com/bouncepaw/mycorrhiza/user" %} {% import "github.com/bouncepaw/mycorrhiza/user" %}
{% import "github.com/bouncepaw/mycorrhiza/util" %} {% import "github.com/bouncepaw/mycorrhiza/util" %}
{% import "github.com/bouncepaw/mycorrhiza/viewutil" %}
{% func MediaMenu(rq *http.Request, h hyphae.Hypha, u *user.User) %} {% func MediaMenu(rq *http.Request, h hyphae.Hypha, u *user.User) %}
{% code {% code
@ -85,7 +86,7 @@
If `contents` == "", a helpful message is shown instead. If `contents` == "", a helpful message is shown instead.
If you rename .prevnext, change the docs too. 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 {% code
siblings, subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName()) siblings, subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName())
lc := meta.Lc lc := meta.Lc

View File

@ -37,599 +37,602 @@ import "github.com/bouncepaw/mycorrhiza/user"
//line views/readers.qtpl:12 //line views/readers.qtpl:12
import "github.com/bouncepaw/mycorrhiza/util" 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 ( import (
qtio422016 "io" qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate" qt422016 "github.com/valyala/quicktemplate"
) )
//line views/readers.qtpl:14 //line views/readers.qtpl:15
var ( var (
_ = qtio422016.Copy _ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer _ = 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) { 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(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:16 //line views/readers.qtpl:17
lc := l18n.FromRequest(rq) lc := l18n.FromRequest(rq)
//line views/readers.qtpl:17 //line views/readers.qtpl:18
qw422016.N().S(` qw422016.N().S(`
<div class="layout"> <div class="layout">
<main class="main-width media-tab"> <main class="main-width media-tab">
<h1>`) <h1>`)
//line views/readers.qtpl:20 //line views/readers.qtpl:21
qw422016.N().S(lc.Get("ui.media_title", &l18n.Replacements{"name": beautifulLink(h.CanonicalName())})) 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(`</h1> qw422016.N().S(`</h1>
`) `)
//line views/readers.qtpl:21 //line views/readers.qtpl:22
switch h.(type) { switch h.(type) {
//line views/readers.qtpl:22 //line views/readers.qtpl:23
case *hyphae.MediaHypha: case *hyphae.MediaHypha:
//line views/readers.qtpl:22 //line views/readers.qtpl:23
qw422016.N().S(` qw422016.N().S(`
<p class="explanation">`) <p class="explanation">`)
//line views/readers.qtpl:23 //line views/readers.qtpl:24
qw422016.E().S(lc.Get("ui.media_tip")) qw422016.E().S(lc.Get("ui.media_tip"))
//line views/readers.qtpl:23 //line views/readers.qtpl:24
qw422016.N().S(` <a href="/help/en/media" class="shy-link">`) qw422016.N().S(` <a href="/help/en/media" class="shy-link">`)
//line views/readers.qtpl:23 //line views/readers.qtpl:24
qw422016.E().S(lc.Get("ui.media_what_is")) qw422016.E().S(lc.Get("ui.media_what_is"))
//line views/readers.qtpl:23 //line views/readers.qtpl:24
qw422016.N().S(`</a></p> qw422016.N().S(`</a></p>
`) `)
//line views/readers.qtpl:24 //line views/readers.qtpl:25
default: default:
//line views/readers.qtpl:24 //line views/readers.qtpl:25
qw422016.N().S(` qw422016.N().S(`
<p class="explanation">`) <p class="explanation">`)
//line views/readers.qtpl:25 //line views/readers.qtpl:26
qw422016.E().S(lc.Get("ui.media_empty")) qw422016.E().S(lc.Get("ui.media_empty"))
//line views/readers.qtpl:25 //line views/readers.qtpl:26
qw422016.N().S(` <a href="/help/en/media" class="shy-link">`) qw422016.N().S(` <a href="/help/en/media" class="shy-link">`)
//line views/readers.qtpl:25 //line views/readers.qtpl:26
qw422016.E().S(lc.Get("ui.media_what_is")) qw422016.E().S(lc.Get("ui.media_what_is"))
//line views/readers.qtpl:25 //line views/readers.qtpl:26
qw422016.N().S(`</a></p> qw422016.N().S(`</a></p>
`) `)
//line views/readers.qtpl:26 //line views/readers.qtpl:27
} }
//line views/readers.qtpl:26 //line views/readers.qtpl:27
qw422016.N().S(` qw422016.N().S(`
<section class="amnt-grid"> <section class="amnt-grid">
`) `)
//line views/readers.qtpl:29 //line views/readers.qtpl:30
switch h := h.(type) { switch h := h.(type) {
//line views/readers.qtpl:30 //line views/readers.qtpl:31
case *hyphae.MediaHypha: case *hyphae.MediaHypha:
//line views/readers.qtpl:30 //line views/readers.qtpl:31
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:32 //line views/readers.qtpl:33
mime := mimetype.FromExtension(path.Ext(h.MediaFilePath())) mime := mimetype.FromExtension(path.Ext(h.MediaFilePath()))
fileinfo, err := os.Stat(h.MediaFilePath()) fileinfo, err := os.Stat(h.MediaFilePath())
//line views/readers.qtpl:33 //line views/readers.qtpl:34
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:34 //line views/readers.qtpl:35
if err == nil { if err == nil {
//line views/readers.qtpl:34 //line views/readers.qtpl:35
qw422016.N().S(` qw422016.N().S(`
<fieldset class="amnt-menu-block"> <fieldset class="amnt-menu-block">
<legend class="modal__title modal__title_small">`) <legend class="modal__title modal__title_small">`)
//line views/readers.qtpl:36 //line views/readers.qtpl:37
qw422016.E().S(lc.Get("ui.media_stat")) qw422016.E().S(lc.Get("ui.media_stat"))
//line views/readers.qtpl:36 //line views/readers.qtpl:37
qw422016.N().S(`</legend> qw422016.N().S(`</legend>
<p class="modal__confirmation-msg"><b>`) <p class="modal__confirmation-msg"><b>`)
//line views/readers.qtpl:37 //line views/readers.qtpl:38
qw422016.E().S(lc.Get("ui.media_stat_size")) qw422016.E().S(lc.Get("ui.media_stat_size"))
//line views/readers.qtpl:37 //line views/readers.qtpl:38
qw422016.N().S(`</b> `) qw422016.N().S(`</b> `)
//line views/readers.qtpl:37 //line views/readers.qtpl:38
qw422016.E().S(lc.GetPlural64("ui.media_size_value", fileinfo.Size())) qw422016.E().S(lc.GetPlural64("ui.media_size_value", fileinfo.Size()))
//line views/readers.qtpl:37 //line views/readers.qtpl:38
qw422016.N().S(`</p> qw422016.N().S(`</p>
<p><b>`) <p><b>`)
//line views/readers.qtpl:38 //line views/readers.qtpl:39
qw422016.E().S(lc.Get("ui.media_stat_mime")) qw422016.E().S(lc.Get("ui.media_stat_mime"))
//line views/readers.qtpl:38 //line views/readers.qtpl:39
qw422016.N().S(`</b> `) qw422016.N().S(`</b> `)
//line views/readers.qtpl:38 //line views/readers.qtpl:39
qw422016.E().S(mime) qw422016.E().S(mime)
//line views/readers.qtpl:38 //line views/readers.qtpl:39
qw422016.N().S(`</p> qw422016.N().S(`</p>
</fieldset> </fieldset>
`) `)
//line views/readers.qtpl:40 //line views/readers.qtpl:41
} }
//line views/readers.qtpl:40 //line views/readers.qtpl:41
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:42 //line views/readers.qtpl:43
if strings.HasPrefix(mime, "image/") { if strings.HasPrefix(mime, "image/") {
//line views/readers.qtpl:42 //line views/readers.qtpl:43
qw422016.N().S(` qw422016.N().S(`
<fieldset class="amnt-menu-block"> <fieldset class="amnt-menu-block">
<legend class="modal__title modal__title_small">`) <legend class="modal__title modal__title_small">`)
//line views/readers.qtpl:44 //line views/readers.qtpl:45
qw422016.E().S(lc.Get("ui.media_include")) qw422016.E().S(lc.Get("ui.media_include"))
//line views/readers.qtpl:44 //line views/readers.qtpl:45
qw422016.N().S(`</legend> qw422016.N().S(`</legend>
<p class="modal__confirmation-msg">`) <p class="modal__confirmation-msg">`)
//line views/readers.qtpl:45 //line views/readers.qtpl:46
qw422016.E().S(lc.Get("ui.media_include_tip")) qw422016.E().S(lc.Get("ui.media_include_tip"))
//line views/readers.qtpl:45 //line views/readers.qtpl:46
qw422016.N().S(`</p> qw422016.N().S(`</p>
<pre class="codeblock"><code>img { `) <pre class="codeblock"><code>img { `)
//line views/readers.qtpl:46 //line views/readers.qtpl:47
qw422016.E().S(h.CanonicalName()) qw422016.E().S(h.CanonicalName())
//line views/readers.qtpl:46 //line views/readers.qtpl:47
qw422016.N().S(` }</code></pre> qw422016.N().S(` }</code></pre>
</fieldset> </fieldset>
`) `)
//line views/readers.qtpl:48 //line views/readers.qtpl:49
} }
//line views/readers.qtpl:48 //line views/readers.qtpl:49
qw422016.N().S(` 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(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:51 //line views/readers.qtpl:52
if u.CanProceed("upload-binary") { if u.CanProceed("upload-binary") {
//line views/readers.qtpl:51 //line views/readers.qtpl:52
qw422016.N().S(` qw422016.N().S(`
<form action="/upload-binary/`) <form action="/upload-binary/`)
//line views/readers.qtpl:52 //line views/readers.qtpl:53
qw422016.E().S(h.CanonicalName()) qw422016.E().S(h.CanonicalName())
//line views/readers.qtpl:52 //line views/readers.qtpl:53
qw422016.N().S(`" qw422016.N().S(`"
method="post" enctype="multipart/form-data" method="post" enctype="multipart/form-data"
class="upload-binary modal amnt-menu-block"> class="upload-binary modal amnt-menu-block">
<fieldset class="modal__fieldset"> <fieldset class="modal__fieldset">
<legend class="modal__title modal__title_small">`) <legend class="modal__title modal__title_small">`)
//line views/readers.qtpl:56 //line views/readers.qtpl:57
qw422016.E().S(lc.Get("ui.media_new")) qw422016.E().S(lc.Get("ui.media_new"))
//line views/readers.qtpl:56 //line views/readers.qtpl:57
qw422016.N().S(`</legend> qw422016.N().S(`</legend>
<p class="modal__confirmation-msg">`) <p class="modal__confirmation-msg">`)
//line views/readers.qtpl:57 //line views/readers.qtpl:58
qw422016.E().S(lc.Get("ui.media_new_tip")) qw422016.E().S(lc.Get("ui.media_new_tip"))
//line views/readers.qtpl:57 //line views/readers.qtpl:58
qw422016.N().S(`</p> qw422016.N().S(`</p>
<label for="upload-binary__input"></label> <label for="upload-binary__input"></label>
<input type="file" id="upload-binary__input" name="binary"> <input type="file" id="upload-binary__input" name="binary">
<button type="submit" class="btn stick-to-bottom" value="Upload">`) <button type="submit" class="btn stick-to-bottom" value="Upload">`)
//line views/readers.qtpl:61 //line views/readers.qtpl:62
qw422016.E().S(lc.Get("ui.media_upload")) qw422016.E().S(lc.Get("ui.media_upload"))
//line views/readers.qtpl:61 //line views/readers.qtpl:62
qw422016.N().S(`</button> qw422016.N().S(`</button>
</fieldset> </fieldset>
</form> </form>
`) `)
//line views/readers.qtpl:64 //line views/readers.qtpl:65
} }
//line views/readers.qtpl:64 //line views/readers.qtpl:65
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:67 //line views/readers.qtpl:68
switch h := h.(type) { switch h := h.(type) {
//line views/readers.qtpl:68 //line views/readers.qtpl:69
case *hyphae.MediaHypha: case *hyphae.MediaHypha:
//line views/readers.qtpl:68 //line views/readers.qtpl:69
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:69 //line views/readers.qtpl:70
if u.CanProceed("remove-media") { if u.CanProceed("remove-media") {
//line views/readers.qtpl:69 //line views/readers.qtpl:70
qw422016.N().S(` qw422016.N().S(`
<form action="/remove-media/`) <form action="/remove-media/`)
//line views/readers.qtpl:70 //line views/readers.qtpl:71
qw422016.E().S(h.CanonicalName()) qw422016.E().S(h.CanonicalName())
//line views/readers.qtpl:70 //line views/readers.qtpl:71
qw422016.N().S(`" method="post" class="modal amnt-menu-block" method="POST"> qw422016.N().S(`" method="post" class="modal amnt-menu-block" method="POST">
<fieldset class="modal__fieldset"> <fieldset class="modal__fieldset">
<legend class="modal__title modal__title_small">`) <legend class="modal__title modal__title_small">`)
//line views/readers.qtpl:72 //line views/readers.qtpl:73
qw422016.E().S(lc.Get("ui.media_remove")) qw422016.E().S(lc.Get("ui.media_remove"))
//line views/readers.qtpl:72 //line views/readers.qtpl:73
qw422016.N().S(`</legend> qw422016.N().S(`</legend>
<p class="modal__confirmation-msg">`) <p class="modal__confirmation-msg">`)
//line views/readers.qtpl:73 //line views/readers.qtpl:74
qw422016.E().S(lc.Get("ui.media_remove_tip")) qw422016.E().S(lc.Get("ui.media_remove_tip"))
//line views/readers.qtpl:73 //line views/readers.qtpl:74
qw422016.N().S(`</p> qw422016.N().S(`</p>
<button type="submit" class="btn" value="Remove media">`) <button type="submit" class="btn" value="Remove media">`)
//line views/readers.qtpl:74 //line views/readers.qtpl:75
qw422016.E().S(lc.Get("ui.media_remove_button")) qw422016.E().S(lc.Get("ui.media_remove_button"))
//line views/readers.qtpl:74 //line views/readers.qtpl:75
qw422016.N().S(`</button> qw422016.N().S(`</button>
</fieldset> </fieldset>
</form> </form>
`) `)
//line views/readers.qtpl:77 //line views/readers.qtpl:78
} }
//line views/readers.qtpl:77 //line views/readers.qtpl:78
qw422016.N().S(` 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(` qw422016.N().S(`
</section> </section>
</main> </main>
</div> </div>
`) `)
//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) { 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) qw422016 := qt422016.AcquireWriter(qq422016)
//line views/readers.qtpl:83 //line views/readers.qtpl:84
StreamMediaMenu(qw422016, rq, h, u) StreamMediaMenu(qw422016, rq, h, u)
//line views/readers.qtpl:83 //line views/readers.qtpl:84
qt422016.ReleaseWriter(qw422016) 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 { 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() qb422016 := qt422016.AcquireByteBuffer()
//line views/readers.qtpl:83 //line views/readers.qtpl:84
WriteMediaMenu(qb422016, rq, h, u) WriteMediaMenu(qb422016, rq, h, u)
//line views/readers.qtpl:83 //line views/readers.qtpl:84
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line views/readers.qtpl:83 //line views/readers.qtpl:84
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line views/readers.qtpl:83 //line views/readers.qtpl:84
return qs422016 return qs422016
//line views/readers.qtpl:83 //line views/readers.qtpl:84
} }
// If `contents` == "", a helpful message is shown instead. // If `contents` == "", a helpful message is shown instead.
// //
// If you rename .prevnext, change the docs too. // If you rename .prevnext, change the docs too.
//line views/readers.qtpl:88 //line views/readers.qtpl:89
func StreamHypha(qw422016 *qt422016.Writer, meta Meta, h hyphae.Hypha, contents string) { func StreamHypha(qw422016 *qt422016.Writer, meta viewutil.Meta, h hyphae.Hypha, contents string) {
//line views/readers.qtpl:88 //line views/readers.qtpl:89
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:90 //line views/readers.qtpl:91
siblings, subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName()) siblings, subhyphae, prevHyphaName, nextHyphaName := tree.Tree(h.CanonicalName())
lc := meta.Lc lc := meta.Lc
//line views/readers.qtpl:92 //line views/readers.qtpl:93
qw422016.N().S(` qw422016.N().S(`
<div class="layout"> <div class="layout">
<main class="main-width"> <main class="main-width">
<section id="hypha"> <section id="hypha">
`) `)
//line views/readers.qtpl:96 //line views/readers.qtpl:97
if meta.U.CanProceed("edit") { if meta.U.CanProceed("edit") {
//line views/readers.qtpl:96 //line views/readers.qtpl:97
qw422016.N().S(` qw422016.N().S(`
<div class="btn btn_navititle"> <div class="btn btn_navititle">
<a class="btn__link_navititle" href="/edit/`) <a class="btn__link_navititle" href="/edit/`)
//line views/readers.qtpl:98 //line views/readers.qtpl:99
qw422016.E().S(h.CanonicalName()) qw422016.E().S(h.CanonicalName())
//line views/readers.qtpl:98 //line views/readers.qtpl:99
qw422016.N().S(`">`) qw422016.N().S(`">`)
//line views/readers.qtpl:98 //line views/readers.qtpl:99
qw422016.E().S(lc.Get("ui.edit_link")) qw422016.E().S(lc.Get("ui.edit_link"))
//line views/readers.qtpl:98 //line views/readers.qtpl:99
qw422016.N().S(`</a> qw422016.N().S(`</a>
</div> </div>
`) `)
//line views/readers.qtpl:100 //line views/readers.qtpl:101
} }
//line views/readers.qtpl:100 //line views/readers.qtpl:101
qw422016.N().S(` 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+"/") { 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(` qw422016.N().S(`
<div class="btn btn_navititle"> <div class="btn btn_navititle">
<a class="btn__link_navititle" href="/logout">`) <a class="btn__link_navititle" href="/logout">`)
//line views/readers.qtpl:104 //line views/readers.qtpl:105
qw422016.E().S(lc.Get("ui.logout_link")) qw422016.E().S(lc.Get("ui.logout_link"))
//line views/readers.qtpl:104 //line views/readers.qtpl:105
qw422016.N().S(`</a> qw422016.N().S(`</a>
</div> </div>
`) `)
//line views/readers.qtpl:106 //line views/readers.qtpl:107
if meta.U.Group == "admin" { if meta.U.Group == "admin" {
//line views/readers.qtpl:106 //line views/readers.qtpl:107
qw422016.N().S(` qw422016.N().S(`
<div class="btn btn_navititle"> <div class="btn btn_navititle">
<a class="btn__link_navititle" href="/admin">`) <a class="btn__link_navititle" href="/admin">`)
//line views/readers.qtpl:108 //line views/readers.qtpl:109
qw422016.E().S(lc.Get("ui.admin_panel")) qw422016.E().S(lc.Get("ui.admin_panel"))
//line views/readers.qtpl:108 //line views/readers.qtpl:109
qw422016.N().S(`<a> qw422016.N().S(`<a>
</div> </div>
`) `)
//line views/readers.qtpl:110 //line views/readers.qtpl:111
} }
//line views/readers.qtpl:110 //line views/readers.qtpl:111
qw422016.N().S(` 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(` qw422016.N().S(`
`)
//line views/readers.qtpl:113
qw422016.N().S(NaviTitle(h))
//line views/readers.qtpl:113
qw422016.N().S(`
`) `)
//line views/readers.qtpl:114 //line views/readers.qtpl:114
qw422016.N().S(NaviTitle(h))
//line views/readers.qtpl:114
qw422016.N().S(`
`)
//line views/readers.qtpl:115
switch h.(type) { switch h.(type) {
//line views/readers.qtpl:115 //line views/readers.qtpl:116
case *hyphae.EmptyHypha: case *hyphae.EmptyHypha:
//line views/readers.qtpl:115 //line views/readers.qtpl:116
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:116 //line views/readers.qtpl:117
streamnonExistentHyphaNotice(qw422016, h, meta.U, meta.Lc) streamnonExistentHyphaNotice(qw422016, h, meta.U, meta.Lc)
//line views/readers.qtpl:116 //line views/readers.qtpl:117
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:117 //line views/readers.qtpl:118
default: default:
//line views/readers.qtpl:117 //line views/readers.qtpl:118
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:118 //line views/readers.qtpl:119
qw422016.N().S(contents) qw422016.N().S(contents)
//line views/readers.qtpl:118 //line views/readers.qtpl:119
qw422016.N().S(` 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(` qw422016.N().S(`
</section> </section>
<section class="prevnext"> <section class="prevnext">
`) `)
//line views/readers.qtpl:122 //line views/readers.qtpl:123
if prevHyphaName != "" { if prevHyphaName != "" {
//line views/readers.qtpl:122 //line views/readers.qtpl:123
qw422016.N().S(` qw422016.N().S(`
<a class="prevnext__el prevnext__prev" href="/hypha/`) <a class="prevnext__el prevnext__prev" href="/hypha/`)
//line views/readers.qtpl:123 //line views/readers.qtpl:124
qw422016.E().S(prevHyphaName) qw422016.E().S(prevHyphaName)
//line views/readers.qtpl:123 //line views/readers.qtpl:124
qw422016.N().S(`" rel="prev">← `) qw422016.N().S(`" rel="prev">← `)
//line views/readers.qtpl:123 //line views/readers.qtpl:124
qw422016.E().S(util.BeautifulName(path.Base(prevHyphaName))) qw422016.E().S(util.BeautifulName(path.Base(prevHyphaName)))
//line views/readers.qtpl:123 //line views/readers.qtpl:124
qw422016.N().S(`</a> qw422016.N().S(`</a>
`) `)
//line views/readers.qtpl:124 //line views/readers.qtpl:125
} }
//line views/readers.qtpl:124 //line views/readers.qtpl:125
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:125 //line views/readers.qtpl:126
if nextHyphaName != "" { if nextHyphaName != "" {
//line views/readers.qtpl:125 //line views/readers.qtpl:126
qw422016.N().S(` qw422016.N().S(`
<a class="prevnext__el prevnext__next" href="/hypha/`) <a class="prevnext__el prevnext__next" href="/hypha/`)
//line views/readers.qtpl:126 //line views/readers.qtpl:127
qw422016.E().S(nextHyphaName) qw422016.E().S(nextHyphaName)
//line views/readers.qtpl:126 //line views/readers.qtpl:127
qw422016.N().S(`" rel="next">`) qw422016.N().S(`" rel="next">`)
//line views/readers.qtpl:126 //line views/readers.qtpl:127
qw422016.E().S(util.BeautifulName(path.Base(nextHyphaName))) qw422016.E().S(util.BeautifulName(path.Base(nextHyphaName)))
//line views/readers.qtpl:126 //line views/readers.qtpl:127
qw422016.N().S(` </a> qw422016.N().S(` </a>
`) `)
//line views/readers.qtpl:127 //line views/readers.qtpl:128
} }
//line views/readers.qtpl:127 //line views/readers.qtpl:128
qw422016.N().S(` qw422016.N().S(`
</section> </section>
`) `)
//line views/readers.qtpl:129 //line views/readers.qtpl:130
StreamSubhyphae(qw422016, subhyphae, meta.Lc) StreamSubhyphae(qw422016, subhyphae, meta.Lc)
//line views/readers.qtpl:129 //line views/readers.qtpl:130
qw422016.N().S(` qw422016.N().S(`
<section id="hypha-bottom"> <section id="hypha-bottom">
`) `)
//line views/readers.qtpl:131 //line views/readers.qtpl:132
streamhyphaInfo(qw422016, meta, h) streamhyphaInfo(qw422016, meta, h)
//line views/readers.qtpl:131 //line views/readers.qtpl:132
qw422016.N().S(` qw422016.N().S(`
</section> </section>
</main> </main>
`) `)
//line views/readers.qtpl:134 //line views/readers.qtpl:135
qw422016.N().S(categoryCard(meta, h.CanonicalName())) qw422016.N().S(categoryCard(meta, h.CanonicalName()))
//line views/readers.qtpl:134 //line views/readers.qtpl:135
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:135 //line views/readers.qtpl:136
streamsiblingHyphae(qw422016, siblings, meta.Lc) streamsiblingHyphae(qw422016, siblings, meta.Lc)
//line views/readers.qtpl:135 //line views/readers.qtpl:136
qw422016.N().S(` qw422016.N().S(`
</div> </div>
`) `)
//line views/readers.qtpl:137 //line views/readers.qtpl:138
streamviewScripts(qw422016) streamviewScripts(qw422016)
//line views/readers.qtpl:137 //line views/readers.qtpl:138
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:138 //line views/readers.qtpl:139
} }
//line views/readers.qtpl:138 //line views/readers.qtpl:139
func WriteHypha(qq422016 qtio422016.Writer, meta Meta, h hyphae.Hypha, contents string) { func WriteHypha(qq422016 qtio422016.Writer, meta viewutil.Meta, h hyphae.Hypha, contents string) {
//line views/readers.qtpl:138 //line views/readers.qtpl:139
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line views/readers.qtpl:138 //line views/readers.qtpl:139
StreamHypha(qw422016, meta, h, contents) StreamHypha(qw422016, meta, h, contents)
//line views/readers.qtpl:138 //line views/readers.qtpl:139
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line views/readers.qtpl:138 //line views/readers.qtpl:139
} }
//line views/readers.qtpl:138 //line views/readers.qtpl:139
func Hypha(meta Meta, h hyphae.Hypha, contents string) string { func Hypha(meta viewutil.Meta, h hyphae.Hypha, contents string) string {
//line views/readers.qtpl:138 //line views/readers.qtpl:139
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line views/readers.qtpl:138 //line views/readers.qtpl:139
WriteHypha(qb422016, meta, h, contents) WriteHypha(qb422016, meta, h, contents)
//line views/readers.qtpl:138 //line views/readers.qtpl:139
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line views/readers.qtpl:138 //line views/readers.qtpl:139
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line views/readers.qtpl:138 //line views/readers.qtpl:139
return qs422016 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) { 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(` qw422016.N().S(`
<div class="layout"> <div class="layout">
<main class="main-width"> <main class="main-width">
<section> <section>
<p>`) <p>`)
//line views/readers.qtpl:144 //line views/readers.qtpl:145
qw422016.E().S(lc.Get("ui.revision_warning")) qw422016.E().S(lc.Get("ui.revision_warning"))
//line views/readers.qtpl:144 //line views/readers.qtpl:145
qw422016.N().S(` <a href="/rev-text/`) qw422016.N().S(` <a href="/rev-text/`)
//line views/readers.qtpl:144 //line views/readers.qtpl:145
qw422016.E().S(revHash) qw422016.E().S(revHash)
//line views/readers.qtpl:144 //line views/readers.qtpl:145
qw422016.N().S(`/`) qw422016.N().S(`/`)
//line views/readers.qtpl:144 //line views/readers.qtpl:145
qw422016.E().S(h.CanonicalName()) qw422016.E().S(h.CanonicalName())
//line views/readers.qtpl:144 //line views/readers.qtpl:145
qw422016.N().S(`">`) qw422016.N().S(`">`)
//line views/readers.qtpl:144 //line views/readers.qtpl:145
qw422016.E().S(lc.Get("ui.revision_link")) qw422016.E().S(lc.Get("ui.revision_link"))
//line views/readers.qtpl:144 //line views/readers.qtpl:145
qw422016.N().S(`</a></p> qw422016.N().S(`</a></p>
`) `)
//line views/readers.qtpl:145 //line views/readers.qtpl:146
qw422016.N().S(NaviTitle(h)) qw422016.N().S(NaviTitle(h))
//line views/readers.qtpl:145 //line views/readers.qtpl:146
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:146 //line views/readers.qtpl:147
qw422016.N().S(contents) qw422016.N().S(contents)
//line views/readers.qtpl:146 //line views/readers.qtpl:147
qw422016.N().S(` qw422016.N().S(`
</section> </section>
</main> </main>
</div> </div>
`) `)
//line views/readers.qtpl:150 //line views/readers.qtpl:151
streamviewScripts(qw422016) streamviewScripts(qw422016)
//line views/readers.qtpl:150 //line views/readers.qtpl:151
qw422016.N().S(` 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) { 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) qw422016 := qt422016.AcquireWriter(qq422016)
//line views/readers.qtpl:151 //line views/readers.qtpl:152
StreamRevision(qw422016, rq, lc, h, contents, revHash) StreamRevision(qw422016, rq, lc, h, contents, revHash)
//line views/readers.qtpl:151 //line views/readers.qtpl:152
qt422016.ReleaseWriter(qw422016) 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 { 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() qb422016 := qt422016.AcquireByteBuffer()
//line views/readers.qtpl:151 //line views/readers.qtpl:152
WriteRevision(qb422016, rq, lc, h, contents, revHash) WriteRevision(qb422016, rq, lc, h, contents, revHash)
//line views/readers.qtpl:151 //line views/readers.qtpl:152
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line views/readers.qtpl:151 //line views/readers.qtpl:152
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line views/readers.qtpl:151 //line views/readers.qtpl:152
return qs422016 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) { func streamviewScripts(qw422016 *qt422016.Writer) {
//line views/readers.qtpl:153 //line views/readers.qtpl:154
qw422016.N().S(` qw422016.N().S(`
`) `)
//line views/readers.qtpl:154 //line views/readers.qtpl:155
for _, scriptPath := range cfg.ViewScripts { for _, scriptPath := range cfg.ViewScripts {
//line views/readers.qtpl:154 //line views/readers.qtpl:155
qw422016.N().S(` qw422016.N().S(`
<script src="`) <script src="`)
//line views/readers.qtpl:155 //line views/readers.qtpl:156
qw422016.E().S(scriptPath) qw422016.E().S(scriptPath)
//line views/readers.qtpl:155 //line views/readers.qtpl:156
qw422016.N().S(`"></script> qw422016.N().S(`"></script>
`) `)
//line views/readers.qtpl:156 //line views/readers.qtpl:157
} }
//line views/readers.qtpl:156 //line views/readers.qtpl:157
qw422016.N().S(` 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) { func writeviewScripts(qq422016 qtio422016.Writer) {
//line views/readers.qtpl:157 //line views/readers.qtpl:158
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line views/readers.qtpl:157 //line views/readers.qtpl:158
streamviewScripts(qw422016) streamviewScripts(qw422016)
//line views/readers.qtpl:157 //line views/readers.qtpl:158
qt422016.ReleaseWriter(qw422016) 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 { func viewScripts() string {
//line views/readers.qtpl:157 //line views/readers.qtpl:158
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line views/readers.qtpl:157 //line views/readers.qtpl:158
writeviewScripts(qb422016) writeviewScripts(qb422016)
//line views/readers.qtpl:157 //line views/readers.qtpl:158
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line views/readers.qtpl:157 //line views/readers.qtpl:158
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line views/readers.qtpl:157 //line views/readers.qtpl:158
return qs422016 return qs422016
//line views/readers.qtpl:157 //line views/readers.qtpl:158
} }

83
viewutil/base.html Normal file
View File

@ -0,0 +1,83 @@
{{define "base"}}
<!doctype html>
<html lang="{{.Meta.Locale}}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{.Title}}</title>
<link rel="shortcut icon" href="/static/favicon.ico">
<link rel="stylesheet" href="/static/style.css">
<script src="/static/shortcuts.js"></script>
{{range .HeadElements}}{{.}}{{end}}
</head>
<body>
<header>
<nav class="main-width top-bar">
<ul class="top-bar__wrapper">
<li class="top-bar__section top-bar__section_home">
<div class="top-bar__home-link-wrapper">
<a class="top-bar__home-link" href="/">{{block "wiki name" .}}{{end}}</a>
</div>
</li>
<li class="top-bar__section top-bar__section_search">
<form class="top-bar__search" method="GET" action="/title-search">
<input type="text" name="q" class="top-bar__search-bar"
placeholder="{{block `search by title` .}}Search by title{{end}}">
</form>
</li>
<li class="top-bar__section top-bar__section_auth">
{{block "auth" .}}
<ul class="top-bar__auth auth-links">
<li class="auth-links__box auth-links__user-box">
{{if .Meta.U.Group | eq "anon" }}
<a href="/login" class="auth-links__link auth-links__login-link">
{{block "login" .}}Login{{end}}
</a>
{{else}}
<a href="/hypha/{%s cfg.UserHypha %}/{%s u.Name %}" class="auth-links__link auth-links__user-link">
{{beautifulName .Meta.U.Name}}
</a>
{{end}}
</li>
{{block "registration" .}}
{{if .Meta.U.Group | eq "anon"}}
<li class="auth-links__box auth-links__register-box">
<a href="/register" class="auth-links__link auth-links__register-link">
{{block "register" .}}Register{{end}}
</a>
</li>
{{end}}
{{end}}
</ul>
{{end}}
</li>
<li class="top-bar__section top-bar__section_highlights">
<ul class="top-bar__highlights">
{{range .HeaderLinks}}
<li class="top-bar__highlight">
<a class="top-bar__highlight-link" href="{{.Href}}">{{.Display}}</a>
</li>
{{end}}
</ul>
</li>
</ul>
</nav>
</header>
{{block "body" .}}{{end}}
<template id="dialog-template">
<div class="dialog-backdrop"></div>
<div class="dialog" tabindex="0">
<div class="dialog__header">
<h1 class="dialog__title"></h1>
<button class="dialog__close-button" aria-label="{{block `close this dialog` .}}{{end}}"></button>
</div>
<div class="dialog__content"></div>
</div>
</template>
{{range .CommonScripts}}{{.}}{{end}}
<script src="/static/view.js"></script>
</body>
</html>
</html>
{{end}}

28
viewutil/meta.go Normal file
View File

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

85
viewutil/viewutil.go Normal file
View File

@ -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()
}

View File

@ -2,6 +2,7 @@ package web
import ( import (
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/viewutil"
"io" "io"
"log" "log"
"mime" "mime"
@ -35,7 +36,7 @@ func initAdmin(r *mux.Router) {
func handlerAdmin(w http.ResponseWriter, rq *http.Request) { func handlerAdmin(w http.ResponseWriter, rq *http.Request) {
w.Header().Set("Content-Type", "text/html;charset=utf-8") w.Header().Set("Content-Type", "text/html;charset=utf-8")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
views.AdminPanel(views.MetaFrom(w, rq)) views.AdminPanel(viewutil.MetaFrom(w, rq))
} }
// handlerAdminShutdown kills the wiki. // handlerAdminShutdown kills the wiki.

View File

@ -5,6 +5,7 @@ import (
"github.com/bouncepaw/mycorrhiza/user" "github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/views" "github.com/bouncepaw/mycorrhiza/views"
"github.com/bouncepaw/mycorrhiza/viewutil"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"io" "io"
"log" "log"
@ -21,7 +22,7 @@ func initCategories(r *mux.Router) {
func handlerListCategory(w http.ResponseWriter, rq *http.Request) { func handlerListCategory(w http.ResponseWriter, rq *http.Request) {
log.Println("Viewing list of categories") 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) { func handlerCategory(w http.ResponseWriter, rq *http.Request) {
@ -32,7 +33,7 @@ func handlerCategory(w http.ResponseWriter, rq *http.Request) {
return return
} }
log.Println("Viewing category", catName) 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) { func handlerRemoveFromCategory(w http.ResponseWriter, rq *http.Request) {

View File

@ -3,6 +3,7 @@ package web
import ( import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"github.com/bouncepaw/mycorrhiza/viewutil"
"io" "io"
"log" "log"
"net/http" "net/http"
@ -209,7 +210,7 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
util.HTTP404Page(w, util.HTTP404Page(w,
views.Base( views.Base(
util.BeautifulName(hyphaName), util.BeautifulName(hyphaName),
views.Hypha(views.MetaFrom(w, rq), h, contents), views.Hypha(viewutil.MetaFrom(w, rq), h, contents),
lc, lc,
u, u,
openGraph)) openGraph))
@ -231,7 +232,7 @@ func handlerHypha(w http.ResponseWriter, rq *http.Request) {
util.HTTP200Page(w, util.HTTP200Page(w,
views.Base( views.Base(
util.BeautifulName(hyphaName), util.BeautifulName(hyphaName),
views.Hypha(views.MetaFrom(w, rq), h, contents), views.Hypha(viewutil.MetaFrom(w, rq), h, contents),
lc, lc,
u, u,
openGraph)) openGraph))