1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-04 18:19:54 +00:00

History: Isolate primitive diff

This commit is contained in:
Timur Ismagilov 2022-05-18 12:26:33 +03:00
parent 2d81e54f14
commit fdba598c57
7 changed files with 228 additions and 248 deletions

View File

@ -0,0 +1,87 @@
// Package histview provides web stuff for history
package histview
import (
"embed"
"encoding/hex"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/history"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/viewutil"
"github.com/gorilla/mux"
"log"
"net/http"
"strings"
"text/template"
)
func InitHandlers(rtr *mux.Router) {
rtr.PathPrefix("/primitive-diff/").HandlerFunc(handlerPrimitiveDiff)
chainPrimitiveDiff = viewutil.
En(viewutil.CopyEnWith(fs, "view_primitive_diff.html")).
Ru(template.Must(viewutil.CopyRuWith(fs, "view_primitive_diff.html").Parse(ruTranslation)))
}
func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
shorterURL := strings.TrimPrefix(rq.URL.Path, "/primitive-diff/")
revHash, slug, found := strings.Cut(shorterURL, "/")
if !found || len(revHash) < 7 || len(slug) < 1 {
http.Error(w, "403 bad request", http.StatusBadRequest)
return
}
paddedRevHash := revHash
if len(paddedRevHash)%2 != 0 {
paddedRevHash = paddedRevHash[:len(paddedRevHash)-1]
}
if _, err := hex.DecodeString(paddedRevHash); err != nil {
http.Error(w, "403 bad request", http.StatusBadRequest)
return
}
switch h := hyphae.ByName(util.CanonicalName(slug)).(type) {
case *hyphae.EmptyHypha:
http.Error(w, "404 not found", http.StatusNotFound)
case hyphae.ExistingHypha:
text, err := history.PrimitiveDiffAtRevision(h.TextFilePath(), revHash)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
primitiveDiff(viewutil.MetaFrom(w, rq), h, revHash, text)
}
}
var (
//go:embed *.html
fs embed.FS
ruTranslation = `
{{define "diff for at title"}}Разница для {{beautifulName .HyphaName}} для {{.Hash}}{{end}}
{{define "diff for at heading"}}Разница для <a href="/hypha/{{.HyphaName}}">{{beautifulName .HyphaName}}</a> для {{.Hash}}{{end}}
`
chainPrimitiveDiff viewutil.Chain
)
type primitiveDiffData struct {
viewutil.BaseData
HyphaName string
Hash string
Text string
}
func primitiveDiff(meta viewutil.Meta, h hyphae.ExistingHypha, hash, text string) {
if err := chainPrimitiveDiff.Get(meta).ExecuteTemplate(meta.W, "page", primitiveDiffData{
BaseData: viewutil.BaseData{
Meta: meta,
Addr: "/primitive-diff/" + hash + "/" + h.CanonicalName(),
HeaderLinks: cfg.HeaderLinks,
CommonScripts: cfg.CommonScripts,
},
HyphaName: h.CanonicalName(),
Hash: hash,
Text: text,
}); err != nil {
log.Println(err)
}
}

View File

@ -0,0 +1,11 @@
{{define "diff for at title"}}Diff of {{beautifulName .HyphaName}} at {{.Hash}}{{end}}
{{define "diff for at heading"}}Diff of <a href="/hypha/{{.HyphaName}}">{{beautifulName .HyphaName}}</a> at {{.Hash}}{{end}}
{{define "title"}}{{template "diff for at title" .}}{{end}}
{{define "body"}}
<main class="main-width">
<article>
<h1>{{template "diff for at heading" .}}</h1>
<pre class="codeblock"><code>{{.Text}}</code></pre>
</article>
</main>
{{end}}

View File

@ -74,8 +74,6 @@
"recent_subscribe": "Подписаться через {{.rss}}, {{.atom}} или {{.json}}",
"recent_subscribe_json": "JSON-ленту",
"recent_empty": "Не удалось найти последние изменения.",
"diff_title": "Разница для «{{.name}}» из {{.rev}}",
"revision_title": "{{.name}} из {{.rev}}",
"revision_warning": "Обратите внимание, просмотр медиа в истории пока что недоступен.",

View File

@ -4,27 +4,9 @@
{% import "github.com/bouncepaw/mycorrhiza/cfg" %}
{% import "github.com/bouncepaw/mycorrhiza/l18n" %}
{% import "github.com/bouncepaw/mycorrhiza/user" %}
{% import "github.com/bouncepaw/mycorrhiza/hyphae" %}
{% import "github.com/bouncepaw/mycorrhiza/history" %}
{% func PrimitiveDiff(rq *http.Request, h hyphae.ExistingHypha, u *user.User, hash string) %}
{% code
lc := l18n.FromRequest(rq)
text, err := history.PrimitiveDiffAtRevision(h.TextFilePath(), hash)
if err != nil {
text = err.Error()
}
%}
<main class="main-width">
<article>
<h1>{%s= lc.Get("ui.diff_title", &l18n.Replacements{"name": beautifulLink(h.CanonicalName()), "rev": hash}) %}</h1>
<pre class="codeblock"><code>{%s text %}</code></pre>
</article>
</main>
{% endfunc %}
{% func RecentChanges(n int, lc *l18n.Localizer) %}
<main class="main-width recent-changes">
<h1>{%s lc.Get("ui.recent_heading") %}</h1>

View File

@ -20,422 +20,358 @@ import "github.com/bouncepaw/mycorrhiza/cfg"
import "github.com/bouncepaw/mycorrhiza/l18n"
//line views/history.qtpl:7
import "github.com/bouncepaw/mycorrhiza/user"
//line views/history.qtpl:8
import "github.com/bouncepaw/mycorrhiza/hyphae"
//line views/history.qtpl:9
import "github.com/bouncepaw/mycorrhiza/history"
//line views/history.qtpl:12
//line views/history.qtpl:10
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
//line views/history.qtpl:12
//line views/history.qtpl:10
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
//line views/history.qtpl:12
func StreamPrimitiveDiff(qw422016 *qt422016.Writer, rq *http.Request, h hyphae.ExistingHypha, u *user.User, hash string) {
//line views/history.qtpl:12
qw422016.N().S(`
`)
//line views/history.qtpl:14
lc := l18n.FromRequest(rq)
text, err := history.PrimitiveDiffAtRevision(h.TextFilePath(), hash)
if err != nil {
text = err.Error()
}
//line views/history.qtpl:19
qw422016.N().S(`
<main class="main-width">
<article>
<h1>`)
//line views/history.qtpl:22
qw422016.N().S(lc.Get("ui.diff_title", &l18n.Replacements{"name": beautifulLink(h.CanonicalName()), "rev": hash}))
//line views/history.qtpl:22
qw422016.N().S(`</h1>
<pre class="codeblock"><code>`)
//line views/history.qtpl:23
qw422016.E().S(text)
//line views/history.qtpl:23
qw422016.N().S(`</code></pre>
</article>
</main>
`)
//line views/history.qtpl:26
}
//line views/history.qtpl:26
func WritePrimitiveDiff(qq422016 qtio422016.Writer, rq *http.Request, h hyphae.ExistingHypha, u *user.User, hash string) {
//line views/history.qtpl:26
qw422016 := qt422016.AcquireWriter(qq422016)
//line views/history.qtpl:26
StreamPrimitiveDiff(qw422016, rq, h, u, hash)
//line views/history.qtpl:26
qt422016.ReleaseWriter(qw422016)
//line views/history.qtpl:26
}
//line views/history.qtpl:26
func PrimitiveDiff(rq *http.Request, h hyphae.ExistingHypha, u *user.User, hash string) string {
//line views/history.qtpl:26
qb422016 := qt422016.AcquireByteBuffer()
//line views/history.qtpl:26
WritePrimitiveDiff(qb422016, rq, h, u, hash)
//line views/history.qtpl:26
qs422016 := string(qb422016.B)
//line views/history.qtpl:26
qt422016.ReleaseByteBuffer(qb422016)
//line views/history.qtpl:26
return qs422016
//line views/history.qtpl:26
}
//line views/history.qtpl:28
//line views/history.qtpl:10
func StreamRecentChanges(qw422016 *qt422016.Writer, n int, lc *l18n.Localizer) {
//line views/history.qtpl:28
//line views/history.qtpl:10
qw422016.N().S(`
<main class="main-width recent-changes">
<h1>`)
//line views/history.qtpl:30
//line views/history.qtpl:12
qw422016.E().S(lc.Get("ui.recent_heading"))
//line views/history.qtpl:30
//line views/history.qtpl:12
qw422016.N().S(`</h1>
<nav class="recent-changes__count">
`)
//line views/history.qtpl:33
//line views/history.qtpl:15
qw422016.E().S(lc.Get("ui.recent_count_pre"))
//line views/history.qtpl:33
//line views/history.qtpl:15
qw422016.N().S(`
`)
//line views/history.qtpl:34
//line views/history.qtpl:16
for i, m := range []int{20, 50, 100} {
//line views/history.qtpl:34
//line views/history.qtpl:16
qw422016.N().S(`
`)
//line views/history.qtpl:35
//line views/history.qtpl:17
if i > 0 {
//line views/history.qtpl:35
//line views/history.qtpl:17
qw422016.N().S(`
<span aria-hidden="true">|</span>
`)
//line views/history.qtpl:37
//line views/history.qtpl:19
}
//line views/history.qtpl:37
//line views/history.qtpl:19
qw422016.N().S(`
`)
//line views/history.qtpl:38
//line views/history.qtpl:20
if m == n {
//line views/history.qtpl:38
//line views/history.qtpl:20
qw422016.N().S(`
<b>`)
//line views/history.qtpl:39
//line views/history.qtpl:21
qw422016.N().D(m)
//line views/history.qtpl:39
//line views/history.qtpl:21
qw422016.N().S(`</b>
`)
//line views/history.qtpl:40
//line views/history.qtpl:22
} else {
//line views/history.qtpl:40
//line views/history.qtpl:22
qw422016.N().S(`
<a href="/recent-changes/`)
//line views/history.qtpl:41
//line views/history.qtpl:23
qw422016.N().D(m)
//line views/history.qtpl:41
//line views/history.qtpl:23
qw422016.N().S(`">`)
//line views/history.qtpl:41
//line views/history.qtpl:23
qw422016.N().D(m)
//line views/history.qtpl:41
//line views/history.qtpl:23
qw422016.N().S(`</a>
`)
//line views/history.qtpl:42
//line views/history.qtpl:24
}
//line views/history.qtpl:42
//line views/history.qtpl:24
qw422016.N().S(`
`)
//line views/history.qtpl:43
//line views/history.qtpl:25
}
//line views/history.qtpl:43
//line views/history.qtpl:25
qw422016.N().S(`
`)
//line views/history.qtpl:44
//line views/history.qtpl:26
qw422016.E().S(lc.Get("ui.recent_count_post"))
//line views/history.qtpl:44
//line views/history.qtpl:26
qw422016.N().S(`
</nav>
<p><img class="icon" width="20" height="20" src="/static/icon/feed.svg">`)
//line views/history.qtpl:47
//line views/history.qtpl:29
qw422016.N().S(lc.Get("ui.recent_subscribe", &l18n.Replacements{"rss": "<a href=\"/recent-changes-rss\">RSS</a>", "atom": "<a href=\"/recent-changes-atom\">Atom</a>", "json": fmt.Sprintf("<a href=\"/recent-changes-json\">%s</a>", lc.Get("ui.recent_subscribe_json"))}))
//line views/history.qtpl:47
//line views/history.qtpl:29
qw422016.N().S(`</p>
`)
//line views/history.qtpl:54
//line views/history.qtpl:36
qw422016.N().S(`
`)
//line views/history.qtpl:57
//line views/history.qtpl:39
changes := history.RecentChanges(n)
var year, day int
var month time.Month
//line views/history.qtpl:60
//line views/history.qtpl:42
qw422016.N().S(`
<section class="recent-changes__list" role="feed">
`)
//line views/history.qtpl:62
//line views/history.qtpl:44
if len(changes) == 0 {
//line views/history.qtpl:62
//line views/history.qtpl:44
qw422016.N().S(`
<p>`)
//line views/history.qtpl:63
//line views/history.qtpl:45
qw422016.E().S(lc.Get("ui.recent_empty"))
//line views/history.qtpl:63
//line views/history.qtpl:45
qw422016.N().S(`</p>
`)
//line views/history.qtpl:64
//line views/history.qtpl:46
} else {
//line views/history.qtpl:64
//line views/history.qtpl:46
qw422016.N().S(`
`)
//line views/history.qtpl:65
//line views/history.qtpl:47
for i, entry := range changes {
//line views/history.qtpl:65
//line views/history.qtpl:47
qw422016.N().S(`
`)
//line views/history.qtpl:67
//line views/history.qtpl:49
y, m, d := entry.Time.UTC().Date()
//line views/history.qtpl:67
//line views/history.qtpl:49
qw422016.N().S(`
`)
//line views/history.qtpl:68
//line views/history.qtpl:50
if d != day || m != month || y != year {
//line views/history.qtpl:68
//line views/history.qtpl:50
qw422016.N().S(`
<h2 class="recent-changes__heading">
`)
//line views/history.qtpl:70
//line views/history.qtpl:52
qw422016.E().S(fmt.Sprintf("%04d-%02d-%02d", y, m, d))
//line views/history.qtpl:70
//line views/history.qtpl:52
qw422016.N().S(`
</h2>
`)
//line views/history.qtpl:72
//line views/history.qtpl:54
year, month, day = y, m, d
//line views/history.qtpl:72
//line views/history.qtpl:54
qw422016.N().S(`
`)
//line views/history.qtpl:73
//line views/history.qtpl:55
}
//line views/history.qtpl:73
//line views/history.qtpl:55
qw422016.N().S(`
<div class="recent-changes__entry" role="article"
aria-setsize="`)
//line views/history.qtpl:76
//line views/history.qtpl:58
qw422016.N().D(n)
//line views/history.qtpl:76
//line views/history.qtpl:58
qw422016.N().S(`" aria-posinset="`)
//line views/history.qtpl:76
//line views/history.qtpl:58
qw422016.N().D(i)
//line views/history.qtpl:76
//line views/history.qtpl:58
qw422016.N().S(`">
`)
//line views/history.qtpl:77
//line views/history.qtpl:59
qw422016.N().S(recentChanges(entry))
//line views/history.qtpl:77
//line views/history.qtpl:59
qw422016.N().S(`
</div>
`)
//line views/history.qtpl:80
//line views/history.qtpl:62
}
//line views/history.qtpl:80
//line views/history.qtpl:62
qw422016.N().S(`
`)
//line views/history.qtpl:81
//line views/history.qtpl:63
}
//line views/history.qtpl:81
//line views/history.qtpl:63
qw422016.N().S(`
</section>
</main>
`)
//line views/history.qtpl:84
//line views/history.qtpl:66
}
//line views/history.qtpl:84
//line views/history.qtpl:66
func WriteRecentChanges(qq422016 qtio422016.Writer, n int, lc *l18n.Localizer) {
//line views/history.qtpl:84
//line views/history.qtpl:66
qw422016 := qt422016.AcquireWriter(qq422016)
//line views/history.qtpl:84
//line views/history.qtpl:66
StreamRecentChanges(qw422016, n, lc)
//line views/history.qtpl:84
//line views/history.qtpl:66
qt422016.ReleaseWriter(qw422016)
//line views/history.qtpl:84
//line views/history.qtpl:66
}
//line views/history.qtpl:84
//line views/history.qtpl:66
func RecentChanges(n int, lc *l18n.Localizer) string {
//line views/history.qtpl:84
//line views/history.qtpl:66
qb422016 := qt422016.AcquireByteBuffer()
//line views/history.qtpl:84
//line views/history.qtpl:66
WriteRecentChanges(qb422016, n, lc)
//line views/history.qtpl:84
//line views/history.qtpl:66
qs422016 := string(qb422016.B)
//line views/history.qtpl:84
//line views/history.qtpl:66
qt422016.ReleaseByteBuffer(qb422016)
//line views/history.qtpl:84
//line views/history.qtpl:66
return qs422016
//line views/history.qtpl:84
//line views/history.qtpl:66
}
//line views/history.qtpl:86
//line views/history.qtpl:68
func streamrecentChanges(qw422016 *qt422016.Writer, rev history.Revision) {
//line views/history.qtpl:86
//line views/history.qtpl:68
qw422016.N().S(`
<div>
<time class="recent-changes__entry__time">
`)
//line views/history.qtpl:89
//line views/history.qtpl:71
qw422016.E().S(rev.Time.UTC().Format("15:04 UTC"))
//line views/history.qtpl:89
//line views/history.qtpl:71
qw422016.N().S(`
</time>
<span class="recent-changes__entry__message">`)
//line views/history.qtpl:91
//line views/history.qtpl:73
qw422016.E().S(rev.Hash)
//line views/history.qtpl:91
//line views/history.qtpl:73
qw422016.N().S(`</span>
`)
//line views/history.qtpl:93
//line views/history.qtpl:75
if rev.Username != "anon" {
//line views/history.qtpl:93
//line views/history.qtpl:75
qw422016.N().S(`
<span class="recent-changes__entry__author">
&mdash; <a href="/hypha/`)
//line views/history.qtpl:95
//line views/history.qtpl:77
qw422016.E().S(cfg.UserHypha)
//line views/history.qtpl:95
//line views/history.qtpl:77
qw422016.N().S(`/`)
//line views/history.qtpl:95
//line views/history.qtpl:77
qw422016.E().S(rev.Username)
//line views/history.qtpl:95
//line views/history.qtpl:77
qw422016.N().S(`" rel="author">`)
//line views/history.qtpl:95
//line views/history.qtpl:77
qw422016.E().S(rev.Username)
//line views/history.qtpl:95
//line views/history.qtpl:77
qw422016.N().S(`</a>
</span>
`)
//line views/history.qtpl:97
//line views/history.qtpl:79
}
//line views/history.qtpl:97
//line views/history.qtpl:79
qw422016.N().S(`
</div>
<div>
<span class="recent-changes__entry__links">
`)
//line views/history.qtpl:101
//line views/history.qtpl:83
qw422016.N().S(rev.HyphaeLinksHTML())
//line views/history.qtpl:101
//line views/history.qtpl:83
qw422016.N().S(`
</span>
<span class="recent-changes__entry__message">
`)
//line views/history.qtpl:104
//line views/history.qtpl:86
qw422016.E().S(rev.Message)
//line views/history.qtpl:104
//line views/history.qtpl:86
qw422016.N().S(`
</span>
</div>
`)
//line views/history.qtpl:107
//line views/history.qtpl:89
}
//line views/history.qtpl:107
//line views/history.qtpl:89
func writerecentChanges(qq422016 qtio422016.Writer, rev history.Revision) {
//line views/history.qtpl:107
//line views/history.qtpl:89
qw422016 := qt422016.AcquireWriter(qq422016)
//line views/history.qtpl:107
//line views/history.qtpl:89
streamrecentChanges(qw422016, rev)
//line views/history.qtpl:107
//line views/history.qtpl:89
qt422016.ReleaseWriter(qw422016)
//line views/history.qtpl:107
//line views/history.qtpl:89
}
//line views/history.qtpl:107
//line views/history.qtpl:89
func recentChanges(rev history.Revision) string {
//line views/history.qtpl:107
//line views/history.qtpl:89
qb422016 := qt422016.AcquireByteBuffer()
//line views/history.qtpl:107
//line views/history.qtpl:89
writerecentChanges(qb422016, rev)
//line views/history.qtpl:107
//line views/history.qtpl:89
qs422016 := string(qb422016.B)
//line views/history.qtpl:107
//line views/history.qtpl:89
qt422016.ReleaseByteBuffer(qb422016)
//line views/history.qtpl:107
//line views/history.qtpl:89
return qs422016
//line views/history.qtpl:107
//line views/history.qtpl:89
}
//line views/history.qtpl:109
//line views/history.qtpl:91
func StreamHistory(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, list string, lc *l18n.Localizer) {
//line views/history.qtpl:109
//line views/history.qtpl:91
qw422016.N().S(`
<main class="main-width">
<article class="history">
<h1>`)
//line views/history.qtpl:112
//line views/history.qtpl:94
qw422016.N().S(fmt.Sprintf(lc.Get("ui.history_title"), beautifulLink(hyphaName)))
//line views/history.qtpl:112
//line views/history.qtpl:94
qw422016.N().S(`</h1>
`)
//line views/history.qtpl:113
//line views/history.qtpl:95
qw422016.N().S(list)
//line views/history.qtpl:113
//line views/history.qtpl:95
qw422016.N().S(`
</article>
</main>
`)
//line views/history.qtpl:116
//line views/history.qtpl:98
}
//line views/history.qtpl:116
//line views/history.qtpl:98
func WriteHistory(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, list string, lc *l18n.Localizer) {
//line views/history.qtpl:116
//line views/history.qtpl:98
qw422016 := qt422016.AcquireWriter(qq422016)
//line views/history.qtpl:116
//line views/history.qtpl:98
StreamHistory(qw422016, rq, hyphaName, list, lc)
//line views/history.qtpl:116
//line views/history.qtpl:98
qt422016.ReleaseWriter(qw422016)
//line views/history.qtpl:116
//line views/history.qtpl:98
}
//line views/history.qtpl:116
//line views/history.qtpl:98
func History(rq *http.Request, hyphaName, list string, lc *l18n.Localizer) string {
//line views/history.qtpl:116
//line views/history.qtpl:98
qb422016 := qt422016.AcquireByteBuffer()
//line views/history.qtpl:116
//line views/history.qtpl:98
WriteHistory(qb422016, rq, hyphaName, list, lc)
//line views/history.qtpl:116
//line views/history.qtpl:98
qs422016 := string(qb422016.B)
//line views/history.qtpl:116
//line views/history.qtpl:98
qt422016.ReleaseByteBuffer(qb422016)
//line views/history.qtpl:116
//line views/history.qtpl:98
return qs422016
//line views/history.qtpl:116
//line views/history.qtpl:98
}

View File

@ -1,7 +1,6 @@
package web
import (
"encoding/hex"
"fmt"
"github.com/bouncepaw/mycomarkup/v4"
"github.com/bouncepaw/mycorrhiza/shroom"
@ -34,7 +33,6 @@ func initReaders(r *mux.Router) {
r.PathPrefix("/binary/").HandlerFunc(handlerBinary)
r.PathPrefix("/rev/").HandlerFunc(handlerRevision)
r.PathPrefix("/rev-text/").HandlerFunc(handlerRevisionText)
r.PathPrefix("/primitive-diff/").HandlerFunc(handlerPrimitiveDiff)
r.PathPrefix("/media/").HandlerFunc(handlerMedia)
}
@ -53,40 +51,6 @@ func handlerMedia(w http.ResponseWriter, rq *http.Request) {
views.MediaMenu(rq, h, u)))
}
func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq)
shorterURL := strings.TrimPrefix(rq.URL.Path, "/primitive-diff/")
revHash, slug, found := strings.Cut(shorterURL, "/")
if !found || len(revHash) < 7 || len(slug) < 1 {
http.Error(w, "403 bad request", http.StatusBadRequest)
return
}
paddedRevHash := revHash
if len(paddedRevHash)%2 != 0 {
paddedRevHash = paddedRevHash[:len(paddedRevHash)-1]
}
if _, err := hex.DecodeString(paddedRevHash); err != nil {
http.Error(w, "403 bad request", http.StatusBadRequest)
return
}
var (
hyphaName = util.CanonicalName(slug)
h = hyphae.ByName(hyphaName)
user = user.FromRequest(rq)
lc = l18n.FromRequest(rq)
)
switch h := h.(type) {
case *hyphae.EmptyHypha:
w.WriteHeader(http.StatusNotFound)
io.WriteString(w, "404 not found")
case hyphae.ExistingHypha:
util.HTTP200Page(w, views.Base(
viewutil.MetaFrom(w, rq),
lc.Get("ui.diff_title", &l18n.Replacements{"name": util.BeautifulName(hyphaName), "rev": revHash}),
views.PrimitiveDiff(rq, h, user, revHash)))
}
}
// handlerRevisionText sends Mycomarkup text of the hypha at the given revision. See also: handlerRevision, handlerText.
//
// /rev-text/<revHash>/<hyphaName>

View File

@ -5,6 +5,7 @@ import (
"github.com/bouncepaw/mycorrhiza/backlinks"
"github.com/bouncepaw/mycorrhiza/categories"
"github.com/bouncepaw/mycorrhiza/help"
"github.com/bouncepaw/mycorrhiza/history/histview"
"github.com/bouncepaw/mycorrhiza/hypview"
"github.com/bouncepaw/mycorrhiza/misc"
"io"
@ -54,6 +55,7 @@ func Handler() http.Handler {
categories.InitHandlers(wikiRouter)
misc.InitHandlers(wikiRouter)
hypview.Init()
histview.InitHandlers(wikiRouter)
// Admin routes.
if cfg.UseAuth {