1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2025-01-05 17:40:26 +00:00

Show prev/next links

This commit is contained in:
bouncepaw 2020-11-29 16:32:52 +05:00
parent c4e0e4879b
commit 05c12e8452
8 changed files with 205 additions and 119 deletions

View File

@ -1,4 +1,4 @@
# 🍄 MycorrhizaWiki 0.11
# 🍄 MycorrhizaWiki 0.12
A wiki engine.
## Building

View File

@ -39,12 +39,13 @@ func handlerRevision(w http.ResponseWriter, rq *http.Request) {
if err == nil {
contents = markup.ToHtml(hyphaName, textContents)
}
treeHTML, _, _ := tree.Tree(hyphaName, IterateHyphaNamesWith)
page := templates.RevisionHTML(
rq,
hyphaName,
naviTitle(hyphaName),
contents,
tree.TreeAsHtml(hyphaName, IterateHyphaNamesWith),
treeHTML,
revHash,
)
w.Header().Set("Content-Type", "text/html;charset=utf-8")
@ -111,8 +112,9 @@ func handlerPage(w http.ResponseWriter, rq *http.Request) {
contents = binaryHtmlBlock(hyphaName, data) + contents
}
}
treeHTML, prevHypha, nextHypha := tree.Tree(hyphaName, IterateHyphaNamesWith)
util.HTTP200Page(w, base(hyphaName, templates.PageHTML(rq, hyphaName,
naviTitle(hyphaName),
contents,
tree.TreeAsHtml(hyphaName, IterateHyphaNamesWith))))
treeHTML, prevHypha, nextHypha)))
}

3
templates/asset.qtpl Normal file
View File

@ -0,0 +1,3 @@
{% func DefaultCSS() %}
{% cat "default.css" %}
{% endfunc %}

View File

@ -1,27 +1,29 @@
// Code generated by qtc from "css.qtpl". DO NOT EDIT.
// Code generated by qtc from "asset.qtpl". DO NOT EDIT.
// See https://github.com/valyala/quicktemplate for details.
//line templates/css.qtpl:1
//line templates/asset.qtpl:1
package templates
//line templates/css.qtpl:1
//line templates/asset.qtpl:1
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
//line templates/css.qtpl:1
//line templates/asset.qtpl:1
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
//line templates/css.qtpl:1
//line templates/asset.qtpl:1
func StreamDefaultCSS(qw422016 *qt422016.Writer) {
//line templates/css.qtpl:1
//line templates/asset.qtpl:1
qw422016.N().S(`
@media screen and (min-width: 700px) {
`)
//line templates/asset.qtpl:2
qw422016.N().S(`@media screen and (min-width: 700px) {
main {margin: 0 auto; width: 700px;}
}
@media screen and (max-width: 700px) {
@ -56,7 +58,7 @@ article pre.codeblock {background-color:#eee; padding:.5rem; white-space: pre-wr
.binary-container_with-video video,
.binary-container_with-audio audio {width: 100%}
.navi-title a {text-decoration:none;}
.img-gallery { text-align: center; margin-top: .25rem; }
.img-gallery { text-align: center; margin-top: .25rem; margin-bottom: .25rem; }
.img-gallery_many-images { background-color: #eee; border-radius: .25rem; padding: .5rem; }
.img-gallery img { max-width: 100%; max-height: 50vh; }
figure { margin: 0; }
@ -73,32 +75,41 @@ nav ul li {list-style-type:none;margin-right:1rem;}
.rc-entry__hash { font-style: italic; text-align: right; }
.rc-entry__links { grid-column: 1 / span 2; }
.rc-entry__author { font-style: italic; }
.prevnext__el { display: block-inline; min-width: 40%; padding: .5rem; margin-bottom: .25rem; text-decoration: none; background-color: #eee; border-radius: .25rem; }
.prevnext__prev { float: left; }
.prevnext__next { float: right; text-align: right; }
.page-separator { clear: both; }
`)
//line templates/css.qtpl:54
//line templates/asset.qtpl:2
qw422016.N().S(`
`)
//line templates/asset.qtpl:3
}
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
func WriteDefaultCSS(qq422016 qtio422016.Writer) {
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
qw422016 := qt422016.AcquireWriter(qq422016)
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
StreamDefaultCSS(qw422016)
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
qt422016.ReleaseWriter(qw422016)
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
}
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
func DefaultCSS() string {
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
qb422016 := qt422016.AcquireByteBuffer()
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
WriteDefaultCSS(qb422016)
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
qs422016 := string(qb422016.B)
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
qt422016.ReleaseByteBuffer(qb422016)
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
return qs422016
//line templates/css.qtpl:54
//line templates/asset.qtpl:3
}

View File

@ -1,4 +1,3 @@
{% func DefaultCSS() %}
@media screen and (min-width: 700px) {
main {margin: 0 auto; width: 700px;}
}
@ -34,7 +33,7 @@ article pre.codeblock {background-color:#eee; padding:.5rem; white-space: pre-wr
.binary-container_with-video video,
.binary-container_with-audio audio {width: 100%}
.navi-title a {text-decoration:none;}
.img-gallery { text-align: center; margin-top: .25rem; }
.img-gallery { text-align: center; margin-top: .25rem; margin-bottom: .25rem; }
.img-gallery_many-images { background-color: #eee; border-radius: .25rem; padding: .5rem; }
.img-gallery img { max-width: 100%; max-height: 50vh; }
figure { margin: 0; }
@ -51,4 +50,9 @@ nav ul li {list-style-type:none;margin-right:1rem;}
.rc-entry__hash { font-style: italic; text-align: right; }
.rc-entry__links { grid-column: 1 / span 2; }
.rc-entry__author { font-style: italic; }
{% endfunc %}
.prevnext__el { display: block-inline; min-width: 40%; padding: .5rem; margin-bottom: .25rem; text-decoration: none; background-color: #eee; border-radius: .25rem; }
.prevnext__prev { float: left; }
.prevnext__next { float: right; text-align: right; }
.page-separator { clear: both; }

View File

@ -1,4 +1,5 @@
{% import "net/http" %}
{% import "path" %}
{% import "github.com/bouncepaw/mycorrhiza/user" %}
{% func HistoryHTML(rq *http.Request, hyphaName, tbody string) %}
@ -35,7 +36,7 @@
{% endfunc %}
If `contents` == "", a helpful message is shown instead.
{% func PageHTML(rq *http.Request, hyphaName, naviTitle, contents, tree string) %}
{% func PageHTML(rq *http.Request, hyphaName, naviTitle, contents, tree, prevHyphaName, nextHyphaName string) %}
<main>
{%= navHTML(rq, hyphaName, "page") %}
<article>
@ -46,7 +47,15 @@ If `contents` == "", a helpful message is shown instead.
{%s= contents %}
{% endif %}
</article>
<hr/>
<section class="prevnext">
{% if prevHyphaName != "" %}
<a class="prevnext__el prevnext__prev" href="/page/{%s prevHyphaName %}">← {%s path.Base(prevHyphaName) %}</a>
{% endif %}
{% if nextHyphaName != "" %}
<a class="prevnext__el prevnext__next" href="/page/{%s nextHyphaName %}">{%s path.Base(nextHyphaName) %} →</a>
{% endif %}
</section>
<hr class="page-separator"/>
{% if u := user.FromRequest(rq).OrAnon(); !user.AuthUsed || u.Group > user.UserAnon %}
<form action="/upload-binary/{%s hyphaName %}"
method="post" enctype="multipart/form-data">

View File

@ -8,30 +8,33 @@ package templates
import "net/http"
//line templates/http_readers.qtpl:2
import "path"
//line templates/http_readers.qtpl:3
import "github.com/bouncepaw/mycorrhiza/user"
//line templates/http_readers.qtpl:4
//line templates/http_readers.qtpl:5
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
//line templates/http_readers.qtpl:4
//line templates/http_readers.qtpl:5
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
//line templates/http_readers.qtpl:4
//line templates/http_readers.qtpl:5
func StreamHistoryHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, tbody string) {
//line templates/http_readers.qtpl:4
//line templates/http_readers.qtpl:5
qw422016.N().S(`
<main>
`)
//line templates/http_readers.qtpl:6
//line templates/http_readers.qtpl:7
streamnavHTML(qw422016, rq, hyphaName, "history")
//line templates/http_readers.qtpl:6
//line templates/http_readers.qtpl:7
qw422016.N().S(`
<table>
<thead>
@ -43,159 +46,199 @@ func StreamHistoryHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, t
</thead>
<tbody>
`)
//line templates/http_readers.qtpl:16
//line templates/http_readers.qtpl:17
qw422016.N().S(tbody)
//line templates/http_readers.qtpl:16
//line templates/http_readers.qtpl:17
qw422016.N().S(`
</tbody>
</table>
</main>
`)
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
}
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
func WriteHistoryHTML(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, tbody string) {
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
qw422016 := qt422016.AcquireWriter(qq422016)
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
StreamHistoryHTML(qw422016, rq, hyphaName, tbody)
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
qt422016.ReleaseWriter(qw422016)
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
}
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
func HistoryHTML(rq *http.Request, hyphaName, tbody string) string {
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
qb422016 := qt422016.AcquireByteBuffer()
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
WriteHistoryHTML(qb422016, rq, hyphaName, tbody)
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
qs422016 := string(qb422016.B)
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
qt422016.ReleaseByteBuffer(qb422016)
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
return qs422016
//line templates/http_readers.qtpl:20
//line templates/http_readers.qtpl:21
}
//line templates/http_readers.qtpl:22
//line templates/http_readers.qtpl:23
func StreamRevisionHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, tree, revHash string) {
//line templates/http_readers.qtpl:22
//line templates/http_readers.qtpl:23
qw422016.N().S(`
<main>
`)
//line templates/http_readers.qtpl:24
//line templates/http_readers.qtpl:25
streamnavHTML(qw422016, rq, hyphaName, "revision", revHash)
//line templates/http_readers.qtpl:24
//line templates/http_readers.qtpl:25
qw422016.N().S(`
<article>
<p>Please note that viewing binary parts of hyphae is not supported in history for now.</p>
`)
//line templates/http_readers.qtpl:27
//line templates/http_readers.qtpl:28
qw422016.N().S(naviTitle)
//line templates/http_readers.qtpl:27
//line templates/http_readers.qtpl:28
qw422016.N().S(`
`)
//line templates/http_readers.qtpl:28
//line templates/http_readers.qtpl:29
qw422016.N().S(contents)
//line templates/http_readers.qtpl:28
//line templates/http_readers.qtpl:29
qw422016.N().S(`
</article>
<hr/>
<aside>
`)
//line templates/http_readers.qtpl:32
//line templates/http_readers.qtpl:33
qw422016.N().S(tree)
//line templates/http_readers.qtpl:32
//line templates/http_readers.qtpl:33
qw422016.N().S(`
</aside>
</main>
`)
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
}
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
func WriteRevisionHTML(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, tree, revHash string) {
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
qw422016 := qt422016.AcquireWriter(qq422016)
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
StreamRevisionHTML(qw422016, rq, hyphaName, naviTitle, contents, tree, revHash)
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
qt422016.ReleaseWriter(qw422016)
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
}
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
func RevisionHTML(rq *http.Request, hyphaName, naviTitle, contents, tree, revHash string) string {
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
qb422016 := qt422016.AcquireByteBuffer()
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
WriteRevisionHTML(qb422016, rq, hyphaName, naviTitle, contents, tree, revHash)
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
qs422016 := string(qb422016.B)
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
qt422016.ReleaseByteBuffer(qb422016)
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
return qs422016
//line templates/http_readers.qtpl:35
//line templates/http_readers.qtpl:36
}
// If `contents` == "", a helpful message is shown instead.
//line templates/http_readers.qtpl:38
func StreamPageHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, tree string) {
//line templates/http_readers.qtpl:38
//line templates/http_readers.qtpl:39
func StreamPageHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, tree, prevHyphaName, nextHyphaName string) {
//line templates/http_readers.qtpl:39
qw422016.N().S(`
<main>
`)
//line templates/http_readers.qtpl:40
//line templates/http_readers.qtpl:41
streamnavHTML(qw422016, rq, hyphaName, "page")
//line templates/http_readers.qtpl:40
//line templates/http_readers.qtpl:41
qw422016.N().S(`
<article>
`)
//line templates/http_readers.qtpl:42
//line templates/http_readers.qtpl:43
qw422016.N().S(naviTitle)
//line templates/http_readers.qtpl:42
//line templates/http_readers.qtpl:43
qw422016.N().S(`
`)
//line templates/http_readers.qtpl:43
//line templates/http_readers.qtpl:44
if contents == "" {
//line templates/http_readers.qtpl:43
//line templates/http_readers.qtpl:44
qw422016.N().S(`
<p>This hypha has no text. Why not <a href="/edit/`)
//line templates/http_readers.qtpl:44
//line templates/http_readers.qtpl:45
qw422016.E().S(hyphaName)
//line templates/http_readers.qtpl:44
//line templates/http_readers.qtpl:45
qw422016.N().S(`">create it</a>?</p>
`)
//line templates/http_readers.qtpl:45
//line templates/http_readers.qtpl:46
} else {
//line templates/http_readers.qtpl:45
//line templates/http_readers.qtpl:46
qw422016.N().S(`
`)
//line templates/http_readers.qtpl:46
//line templates/http_readers.qtpl:47
qw422016.N().S(contents)
//line templates/http_readers.qtpl:46
//line templates/http_readers.qtpl:47
qw422016.N().S(`
`)
//line templates/http_readers.qtpl:47
//line templates/http_readers.qtpl:48
}
//line templates/http_readers.qtpl:47
//line templates/http_readers.qtpl:48
qw422016.N().S(`
</article>
<hr/>
<section class="prevnext">
`)
//line templates/http_readers.qtpl:51
if prevHyphaName != "" {
//line templates/http_readers.qtpl:51
qw422016.N().S(`
<a class="prevnext__el prevnext__prev" href="/page/`)
//line templates/http_readers.qtpl:52
qw422016.E().S(prevHyphaName)
//line templates/http_readers.qtpl:52
qw422016.N().S(`">← `)
//line templates/http_readers.qtpl:52
qw422016.E().S(path.Base(prevHyphaName))
//line templates/http_readers.qtpl:52
qw422016.N().S(`</a>
`)
//line templates/http_readers.qtpl:53
}
//line templates/http_readers.qtpl:53
qw422016.N().S(`
`)
//line templates/http_readers.qtpl:54
if nextHyphaName != "" {
//line templates/http_readers.qtpl:54
qw422016.N().S(`
<a class="prevnext__el prevnext__next" href="/page/`)
//line templates/http_readers.qtpl:55
qw422016.E().S(nextHyphaName)
//line templates/http_readers.qtpl:55
qw422016.N().S(`">`)
//line templates/http_readers.qtpl:55
qw422016.E().S(path.Base(nextHyphaName))
//line templates/http_readers.qtpl:55
qw422016.N().S(` </a>
`)
//line templates/http_readers.qtpl:56
}
//line templates/http_readers.qtpl:56
qw422016.N().S(`
</section>
<hr class="page-separator"/>
`)
//line templates/http_readers.qtpl:50
//line templates/http_readers.qtpl:59
if u := user.FromRequest(rq).OrAnon(); !user.AuthUsed || u.Group > user.UserAnon {
//line templates/http_readers.qtpl:50
//line templates/http_readers.qtpl:59
qw422016.N().S(`
<form action="/upload-binary/`)
//line templates/http_readers.qtpl:51
//line templates/http_readers.qtpl:60
qw422016.E().S(hyphaName)
//line templates/http_readers.qtpl:51
//line templates/http_readers.qtpl:60
qw422016.N().S(`"
method="post" enctype="multipart/form-data">
<label for="upload-binary__input">Upload a new attachment</label>
@ -205,44 +248,44 @@ func StreamPageHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, navi
</form>
<hr/>
`)
//line templates/http_readers.qtpl:59
//line templates/http_readers.qtpl:68
}
//line templates/http_readers.qtpl:59
//line templates/http_readers.qtpl:68
qw422016.N().S(`
<aside>
`)
//line templates/http_readers.qtpl:61
//line templates/http_readers.qtpl:70
qw422016.N().S(tree)
//line templates/http_readers.qtpl:61
//line templates/http_readers.qtpl:70
qw422016.N().S(`
</aside>
</main>
`)
//line templates/http_readers.qtpl:64
//line templates/http_readers.qtpl:73
}
//line templates/http_readers.qtpl:64
func WritePageHTML(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, tree string) {
//line templates/http_readers.qtpl:64
//line templates/http_readers.qtpl:73
func WritePageHTML(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, tree, prevHyphaName, nextHyphaName string) {
//line templates/http_readers.qtpl:73
qw422016 := qt422016.AcquireWriter(qq422016)
//line templates/http_readers.qtpl:64
StreamPageHTML(qw422016, rq, hyphaName, naviTitle, contents, tree)
//line templates/http_readers.qtpl:64
//line templates/http_readers.qtpl:73
StreamPageHTML(qw422016, rq, hyphaName, naviTitle, contents, tree, prevHyphaName, nextHyphaName)
//line templates/http_readers.qtpl:73
qt422016.ReleaseWriter(qw422016)
//line templates/http_readers.qtpl:64
//line templates/http_readers.qtpl:73
}
//line templates/http_readers.qtpl:64
func PageHTML(rq *http.Request, hyphaName, naviTitle, contents, tree string) string {
//line templates/http_readers.qtpl:64
//line templates/http_readers.qtpl:73
func PageHTML(rq *http.Request, hyphaName, naviTitle, contents, tree, prevHyphaName, nextHyphaName string) string {
//line templates/http_readers.qtpl:73
qb422016 := qt422016.AcquireByteBuffer()
//line templates/http_readers.qtpl:64
WritePageHTML(qb422016, rq, hyphaName, naviTitle, contents, tree)
//line templates/http_readers.qtpl:64
//line templates/http_readers.qtpl:73
WritePageHTML(qb422016, rq, hyphaName, naviTitle, contents, tree, prevHyphaName, nextHyphaName)
//line templates/http_readers.qtpl:73
qs422016 := string(qb422016.B)
//line templates/http_readers.qtpl:64
//line templates/http_readers.qtpl:73
qt422016.ReleaseByteBuffer(qb422016)
//line templates/http_readers.qtpl:64
//line templates/http_readers.qtpl:73
return qs422016
//line templates/http_readers.qtpl:64
//line templates/http_readers.qtpl:73
}

View File

@ -10,17 +10,20 @@ import (
// If Name == "", the tree is empty.
type tree struct {
name string
exists bool
prevSibling string
nextSibling string
siblings []string
descendants []*tree
root bool
hyphaIterator func(func(string))
}
// TreeAsHtml generates a tree for `hyphaName`. `hyphaStorage` has this type because package `tree` has no access to `HyphaData` data type. One day it shall have it, I guess.
func TreeAsHtml(hyphaName string, hyphaIterator func(func(string))) string {
// Tree generates a tree for `hyphaName` as html and returns next and previous hyphae if any.
func Tree(hyphaName string, hyphaIterator func(func(string))) (html, prev, next string) {
t := &tree{name: hyphaName, root: true, hyphaIterator: hyphaIterator}
t.fill()
return t.asHtml()
return t.asHtml(), t.prevSibling, t.nextSibling
}
// subtree adds a descendant tree to `t` and returns that tree.
@ -34,11 +37,22 @@ func (t *tree) fork(descendantName string) *tree {
return subt
}
// Compare current prev next hyphae and decide if any of them should be set to `name2`.
func (t *tree) prevNextDetermine(name2 string) {
if name2 < t.name && (name2 > t.prevSibling || t.prevSibling == "") {
t.prevSibling = name2
} else if name2 > t.name && (name2 < t.nextSibling || t.nextSibling == "") {
t.nextSibling = name2
}
}
// Compares names and does something with them, may generate a subtree.
func (t *tree) compareNamesAndAppend(name2 string) {
switch {
case t.name == name2:
t.exists = true
case t.root && path.Dir(t.name) == path.Dir(name2):
t.prevNextDetermine(name2)
t.siblings = append(t.siblings, name2)
case t.name == path.Dir(name2):
t.fork(name2).fill()