1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-10-30 03:36:16 +00:00
mycorrhiza/render/render.go
Timur Ismagilov 9c2846232c Redo render
2020-06-28 20:02:07 +05:00

131 lines
3.0 KiB
Go

package render
import (
"bytes"
"fmt"
"path"
"text/template"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/fs"
)
// HyphaEdit renders hypha editor.
func HyphaEdit(h *fs.Hypha) []byte { //
hyphaData := map[string]string{
"Name": h.FullName,
"Tags": h.TagsJoined(),
"TextMime": h.TextMime(),
"Text": h.TextContent(),
}
return layout("edit/index").
withMap(hyphaData).
wrapInBase(map[string]string{
"Title": fmt.Sprintf(cfg.TitleEditTemplate, h.FullName),
"Header": layout("edit/header").withString(h.FullName).String(),
"Sidebar": layout("edit/sidebar").withMap(hyphaData).String(),
})
}
// HyphaUpdateOk is used to inform that update was successful.
func HyphaUpdateOk(h *fs.Hypha) []byte { //
return layout("updateOk").
withMap(map[string]string{"Name": h.FullName}).
Bytes()
}
// Hypha404 renders 404 page for nonexistent page.
func Hypha404(name, _ string) []byte {
return hyphaGeneric(name, name, "view/404")
}
// HyphaPage renders hypha viewer.
func HyphaPage(name, content string) []byte {
return hyphaGeneric(name, content, "view/index")
}
// hyphaGeneric is used when building renderers for all types of hypha pages
func hyphaGeneric(name, content, templateName string) []byte {
return layout(templateName).
withString(content).
wrapInBase(map[string]string{
"Title": fmt.Sprintf(cfg.TitleTemplate, name),
"Sidebar": hyphaTree(name),
})
}
// wrapInBase is used to wrap layouts in things that are present on all pages.
func (lyt *Layout) wrapInBase(keys map[string]string) []byte {
page := map[string]string{
"Title": cfg.SiteTitle,
"Main": "",
"SiteTitle": cfg.SiteTitle,
}
for key, val := range keys {
page[key] = val
}
page["Main"] = lyt.String()
return layout("base").withMap(page).Bytes()
}
func hyphaTree(name string) string {
return layout("view/sidebar").
withMap(map[string]string{"Tree": fs.Hs.GetTree(name, true).AsHtml()}).
String()
}
type Layout struct {
tmpl *template.Template
buf *bytes.Buffer
invalid bool
err error
}
func layout(name string) *Layout {
h := fs.Hs.Open(path.Join(cfg.TemplatesDir, cfg.Theme, name+".html")).OnRevision("0")
if h.Invalid {
return &Layout{nil, nil, true, h.Err}
}
tmpl, err := template.ParseFiles(h.TextPath())
if err != nil {
return &Layout{nil, nil, true, err}
}
return &Layout{tmpl, new(bytes.Buffer), false, nil}
}
func (lyt *Layout) withString(data string) *Layout {
if lyt.invalid {
return lyt
}
if err := lyt.tmpl.Execute(lyt.buf, data); err != nil {
lyt.invalid = true
lyt.err = err
}
return lyt
}
func (lyt *Layout) withMap(data map[string]string) *Layout {
if lyt.invalid {
return lyt
}
if err := lyt.tmpl.Execute(lyt.buf, data); err != nil {
lyt.invalid = true
lyt.err = err
}
return lyt
}
func (lyt *Layout) Bytes() []byte {
if lyt.invalid {
return []byte(lyt.err.Error())
}
return lyt.buf.Bytes()
}
func (lyt *Layout) String() string {
if lyt.invalid {
return lyt.err.Error()
}
return lyt.buf.String()
}