Viewutil: Introduce ExecutePage

It reduces the number of boilerplate and guesses some stuff for us. Fighting the templates.
This commit is contained in:
Timur Ismagilov 2022-05-18 19:46:01 +03:00
parent 1a98beccb4
commit 9a540ba022
7 changed files with 82 additions and 125 deletions

View File

@ -2,12 +2,10 @@ package backlinks
import ( import (
"embed" "embed"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/hyphae" "github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/viewutil" "github.com/bouncepaw/mycorrhiza/viewutil"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"log"
"net/http" "net/http"
"sort" "sort"
"text/template" "text/template"
@ -62,41 +60,31 @@ var (
) )
type backlinksData struct { type backlinksData struct {
viewutil.BaseData *viewutil.BaseData
HyphaName string HyphaName string
Backlinks []string Backlinks []string
} }
func viewBacklinks(meta viewutil.Meta, hyphaName string, backlinks []string) { func viewBacklinks(meta viewutil.Meta, hyphaName string, backlinks []string) {
if err := chainBacklinks.Get(meta).ExecuteTemplate(meta.W, "page", backlinksData{ viewutil.ExecutePage(meta, chainBacklinks, backlinksData{
BaseData: viewutil.BaseData{ BaseData: &viewutil.BaseData{
Meta: meta, Addr: "/backlinks/" + hyphaName,
Addr: "/backlinks/" + hyphaName,
HeaderLinks: cfg.HeaderLinks,
CommonScripts: cfg.CommonScripts,
}, },
HyphaName: hyphaName, HyphaName: hyphaName,
Backlinks: backlinks, Backlinks: backlinks,
}); err != nil { })
log.Println(err)
}
} }
type orphansData struct { type orphansData struct {
viewutil.BaseData *viewutil.BaseData
Orphans []string Orphans []string
} }
func viewOrphans(meta viewutil.Meta, orphans []string) { func viewOrphans(meta viewutil.Meta, orphans []string) {
if err := chainOrphans.Get(meta).ExecuteTemplate(meta.W, "page", orphansData{ viewutil.ExecutePage(meta, chainOrphans, orphansData{
BaseData: viewutil.BaseData{ BaseData: &viewutil.BaseData{
Meta: meta, Addr: "/orphans",
Addr: "/orphans",
HeaderLinks: cfg.HeaderLinks,
CommonScripts: cfg.CommonScripts,
}, },
Orphans: orphans, Orphans: orphans,
}); err != nil { })
log.Println(err)
}
} }

View File

@ -2,7 +2,6 @@ package categories
import ( import (
"embed" "embed"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/viewutil" "github.com/bouncepaw/mycorrhiza/viewutil"
"log" "log"
"strings" "strings"
@ -64,42 +63,33 @@ func CategoryCard(meta viewutil.Meta, hyphaName string) string {
} }
type pageData struct { type pageData struct {
viewutil.BaseData *viewutil.BaseData
CatName string CatName string
Hyphae []string Hyphae []string
GivenPermissionToModify bool GivenPermissionToModify bool
} }
func categoryPage(meta viewutil.Meta, catName string) { func categoryPage(meta viewutil.Meta, catName string) {
if err := viewPageChain.Get(meta).ExecuteTemplate(meta.W, "page", pageData{ viewutil.ExecutePage(meta, viewPageChain, pageData{
BaseData: viewutil.BaseData{ BaseData: &viewutil.BaseData{
Meta: meta, Addr: "/category/" + catName,
HeaderLinks: cfg.HeaderLinks,
CommonScripts: cfg.CommonScripts,
Addr: "/category/" + catName,
}, },
CatName: catName, CatName: catName,
Hyphae: hyphaeInCategory(catName), Hyphae: hyphaeInCategory(catName),
GivenPermissionToModify: meta.U.CanProceed("add-to-category"), GivenPermissionToModify: meta.U.CanProceed("add-to-category"),
}); err != nil { })
log.Println(err)
}
} }
type listData struct { type listData struct {
viewutil.BaseData *viewutil.BaseData
Categories []string Categories []string
} }
func categoryList(meta viewutil.Meta) { func categoryList(meta viewutil.Meta) {
if err := viewListChain.Get(meta).ExecuteTemplate(meta.W, "page", listData{ viewutil.ExecutePage(meta, viewListChain, listData{
BaseData: viewutil.BaseData{ BaseData: &viewutil.BaseData{
Meta: meta, Addr: "/category",
HeaderLinks: cfg.HeaderLinks,
CommonScripts: cfg.CommonScripts,
}, },
Categories: listOfCategories(), Categories: listOfCategories(),
}); err != nil { })
log.Println(err)
}
} }

View File

@ -3,11 +3,9 @@ package help
// stuff.go is used for meta stuff about the wiki or all hyphae at once. // stuff.go is used for meta stuff about the wiki or all hyphae at once.
import ( import (
"github.com/bouncepaw/mycomarkup/v4" "github.com/bouncepaw/mycomarkup/v4"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/shroom" "github.com/bouncepaw/mycorrhiza/shroom"
"github.com/bouncepaw/mycorrhiza/viewutil" "github.com/bouncepaw/mycorrhiza/viewutil"
"io" "io"
"log"
"net/http" "net/http"
"strings" "strings"
"text/template" "text/template"
@ -92,22 +90,17 @@ func handlerHelp(w http.ResponseWriter, rq *http.Request) {
} }
type helpData struct { type helpData struct {
viewutil.BaseData *viewutil.BaseData
ContentsHTML string ContentsHTML string
Lang string Lang string
} }
func viewHelp(meta viewutil.Meta, lang, contentsHTML, articlePath string) { func viewHelp(meta viewutil.Meta, lang, contentsHTML, articlePath string) {
if err := chain.Get(meta).ExecuteTemplate(meta.W, "page", helpData{ viewutil.ExecutePage(meta, chain, helpData{
BaseData: viewutil.BaseData{ BaseData: &viewutil.BaseData{
Meta: meta, Addr: "/help/" + articlePath,
HeaderLinks: cfg.HeaderLinks,
CommonScripts: cfg.CommonScripts,
Addr: "/help/" + articlePath,
}, },
ContentsHTML: contentsHTML, ContentsHTML: contentsHTML,
Lang: lang, Lang: lang,
}); err != nil { })
log.Println(err)
}
} }

View File

@ -10,7 +10,6 @@ import (
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"github.com/bouncepaw/mycorrhiza/viewutil" "github.com/bouncepaw/mycorrhiza/viewutil"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"log"
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
@ -79,12 +78,13 @@ var (
{{define "diff for at heading"}}Разница для <a href="/hypha/{{.HyphaName}}">{{beautifulName .HyphaName}}</a> для {{.Hash}}{{end}} {{define "diff for at heading"}}Разница для <a href="/hypha/{{.HyphaName}}">{{beautifulName .HyphaName}}</a> для {{.Hash}}{{end}}
` `
// TODO: translate recent changes
chainPrimitiveDiff viewutil.Chain chainPrimitiveDiff viewutil.Chain
chainRecentChanges viewutil.Chain chainRecentChanges viewutil.Chain
) )
type recentChangesData struct { type recentChangesData struct {
viewutil.BaseData *viewutil.BaseData
EditCount int EditCount int
Changes []history.Revision Changes []history.Revision
UserHypha string UserHypha string
@ -92,41 +92,27 @@ type recentChangesData struct {
} }
func recentChanges(meta viewutil.Meta, editCount int, changes []history.Revision) { func recentChanges(meta viewutil.Meta, editCount int, changes []history.Revision) {
if err := chainRecentChanges.Get(meta).ExecuteTemplate(meta.W, "page", recentChangesData{ viewutil.ExecutePage(meta, chainRecentChanges, recentChangesData{
BaseData: viewutil.BaseData{ BaseData: &viewutil.BaseData{},
Meta: meta,
Addr: "/recent-changes/" + strconv.Itoa(editCount),
HeaderLinks: cfg.HeaderLinks,
CommonScripts: cfg.CommonScripts,
},
EditCount: editCount, EditCount: editCount,
Changes: changes, Changes: changes,
UserHypha: cfg.UserHypha, UserHypha: cfg.UserHypha,
Stops: []int{20, 50, 100}, Stops: []int{20, 50, 100},
}); err != nil { })
log.Println(err)
}
} }
type primitiveDiffData struct { type primitiveDiffData struct {
viewutil.BaseData *viewutil.BaseData
HyphaName string HyphaName string
Hash string Hash string
Text string Text string
} }
func primitiveDiff(meta viewutil.Meta, h hyphae.ExistingHypha, hash, text string) { func primitiveDiff(meta viewutil.Meta, h hyphae.ExistingHypha, hash, text string) {
if err := chainPrimitiveDiff.Get(meta).ExecuteTemplate(meta.W, "page", primitiveDiffData{ viewutil.ExecutePage(meta, chainPrimitiveDiff, primitiveDiffData{
BaseData: viewutil.BaseData{ BaseData: &viewutil.BaseData{},
Meta: meta,
Addr: "/primitive-diff/" + hash + "/" + h.CanonicalName(),
HeaderLinks: cfg.HeaderLinks,
CommonScripts: cfg.CommonScripts,
},
HyphaName: h.CanonicalName(), HyphaName: h.CanonicalName(),
Hash: hash, Hash: hash,
Text: text, Text: text,
}); err != nil { })
log.Println(err)
}
} }

View File

@ -19,6 +19,7 @@ import (
"math/rand" "math/rand"
"mime" "mime"
"net/http" "net/http"
"path/filepath"
) )
func InitHandlers(rtr *mux.Router) { func InitHandlers(rtr *mux.Router) {
@ -41,7 +42,25 @@ func InitHandlers(rtr *mux.Router) {
// handlerList shows a list of all hyphae in the wiki in random order. // handlerList shows a list of all hyphae in the wiki in random order.
func handlerList(w http.ResponseWriter, rq *http.Request) { func handlerList(w http.ResponseWriter, rq *http.Request) {
util.PrepareRq(rq) util.PrepareRq(rq)
viewList(viewutil.MetaFrom(w, rq)) // TODO: make this more effective, there are too many loops and vars
var (
hyphaNames = make(chan string)
sortedHypha = hyphae.PathographicSort(hyphaNames)
entries []listDatum
)
for hypha := range hyphae.YieldExistingHyphae() {
hyphaNames <- hypha.CanonicalName()
}
close(hyphaNames)
for hyphaName := range sortedHypha {
switch h := hyphae.ByName(hyphaName).(type) {
case *hyphae.TextualHypha:
entries = append(entries, listDatum{h.CanonicalName(), ""})
case *hyphae.MediaHypha:
entries = append(entries, listDatum{h.CanonicalName(), filepath.Ext(h.MediaFilePath())[1:]})
}
}
viewList(viewutil.MetaFrom(w, rq), entries)
} }
// handlerReindex reindexes all hyphae by checking the wiki storage directory anew. // handlerReindex reindexes all hyphae by checking the wiki storage directory anew.

View File

@ -2,11 +2,7 @@ package misc
import ( import (
"embed" "embed"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/viewutil" "github.com/bouncepaw/mycorrhiza/viewutil"
"log"
"path/filepath"
"text/template" "text/template"
) )
@ -39,58 +35,27 @@ type listDatum struct {
} }
type listData struct { type listData struct {
viewutil.BaseData *viewutil.BaseData
Entries []listDatum Entries []listDatum
} }
func viewList(meta viewutil.Meta) { func viewList(meta viewutil.Meta, entries []listDatum) {
// TODO: make this more effective, there are too many loops and vars viewutil.ExecutePage(meta, chainList, listData{
var ( BaseData: &viewutil.BaseData{},
hyphaNames = make(chan string) Entries: entries,
sortedHypha = hyphae.PathographicSort(hyphaNames) })
data []listDatum
)
for hypha := range hyphae.YieldExistingHyphae() {
hyphaNames <- hypha.CanonicalName()
}
close(hyphaNames)
for hyphaName := range sortedHypha {
switch h := hyphae.ByName(hyphaName).(type) {
case *hyphae.TextualHypha:
data = append(data, listDatum{h.CanonicalName(), ""})
case *hyphae.MediaHypha:
data = append(data, listDatum{h.CanonicalName(), filepath.Ext(h.MediaFilePath())[1:]})
}
}
if err := chainList.Get(meta).ExecuteTemplate(meta.W, "page", listData{
BaseData: viewutil.BaseData{
Meta: meta,
HeaderLinks: cfg.HeaderLinks,
CommonScripts: cfg.CommonScripts,
},
Entries: data,
}); err != nil {
log.Println(err)
}
} }
type titleSearchData struct { type titleSearchData struct {
viewutil.BaseData *viewutil.BaseData
Query string Query string
Results []string Results []string
} }
func viewTitleSearch(meta viewutil.Meta, query string, results []string) { func viewTitleSearch(meta viewutil.Meta, query string, results []string) {
if err := chainTitleSearch.Get(meta).ExecuteTemplate(meta.W, "page", titleSearchData{ viewutil.ExecutePage(meta, chainTitleSearch, titleSearchData{
BaseData: viewutil.BaseData{ BaseData: &viewutil.BaseData{},
Meta: meta, Query: query,
HeaderLinks: cfg.HeaderLinks, Results: results,
CommonScripts: cfg.CommonScripts, })
},
Query: query,
Results: results,
}); err != nil {
log.Println(err)
}
} }

View File

@ -96,6 +96,12 @@ type BaseData struct {
Body string // TODO: remove Body string // TODO: remove
} }
func (bd *BaseData) withBaseValues(meta Meta, headerLinks []cfg.HeaderLink, commonScripts []string) {
bd.Meta = meta
bd.HeaderLinks = headerLinks
bd.CommonScripts = commonScripts
}
// Base is a temporary wrapper around BaseEn and BaseRu, meant to facilitate the migration from qtpl. // Base is a temporary wrapper around BaseEn and BaseRu, meant to facilitate the migration from qtpl.
func Base(meta Meta, title, body string, headElements ...string) string { func Base(meta Meta, title, body string, headElements ...string) string {
var w strings.Builder var w strings.Builder
@ -122,3 +128,13 @@ func CopyEnWith(fsys fs.FS, f string) *template.Template {
func CopyRuWith(fsys fs.FS, f string) *template.Template { func CopyRuWith(fsys fs.FS, f string) *template.Template {
return m(m(BaseRu.Clone()).ParseFS(fsys, f)) return m(m(BaseRu.Clone()).ParseFS(fsys, f))
} }
// ExecutePage executes template page in the given chain with the given data that has BaseData nested. It also sets some common BaseData fields
func ExecutePage(meta Meta, chain Chain, data interface {
withBaseValues(meta Meta, headerLinks []cfg.HeaderLink, commonScripts []string)
}) {
data.withBaseValues(meta, cfg.HeaderLinks, cfg.CommonScripts)
if err := chain.Get(meta).ExecuteTemplate(meta.W, "page", data); err != nil {
log.Println(err)
}
}