1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-10-30 03:36:16 +00:00
mycorrhiza/viewutil/viewutil.go

162 lines
4.6 KiB
Go
Raw Normal View History

2022-03-29 20:59:36 +00:00
// 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/util"
2022-04-02 07:10:32 +00:00
"io/fs"
2022-03-29 20:59:36 +00:00
"log"
"strings"
"text/template" // TODO: save the world
2022-03-29 20:59:36 +00:00
)
var (
//go:embed *.html
2022-04-02 07:10:32 +00:00
fsys embed.FS
2022-03-29 20:59:36 +00:00
BaseEn *template.Template
BaseRu *template.Template
m = template.Must
)
const ruText = `
{{define "search by title"}}Поиск по названию{{end}}
{{define "close this dialog"}}Закрыть этот диалог{{end}}
{{define "login"}}Войти{{end}}
2022-04-21 14:32:58 +00:00
{{define "register"}}Регистрация{{end}}
2022-06-16 11:05:30 +00:00
{{define "confirm"}}Подтвердить{{end}}
{{define "cancel"}}Отмена{{end}}
{{define "save"}}Сохранить{{end}}
2022-08-06 17:33:37 +00:00
{{define "error"}}Ошибка{{end}}
{{define "delete"}}Удалить{{end}}
2022-03-29 20:59:36 +00:00
`
func Init() {
dataText := fmt.Sprintf(`
{{define "wiki name"}}%s{{end}}
2022-04-21 14:32:58 +00:00
{{define "user hypha"}}%s{{end}}
`, cfg.WikiName, cfg.UserHypha)
BaseEn = m(m(template.New("").
Funcs(template.FuncMap{
"beautifulName": util.BeautifulName,
"inc": func(i int) int { return i + 1 },
2022-04-02 07:10:32 +00:00
}).ParseFS(fsys, "base.html")).
Parse(dataText))
if cfg.UseAuth {
BaseEn = m(BaseEn.Parse(`
{{define "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/{{block "user hypha" .}}{{end}}/{{.Meta.U.Name}}" class="auth-links__link auth-links__user-link">
{{beautifulName .Meta.U.Name}}
</a>
{{end}}
</li>
{{block "registration" .}}{{end}}
</ul>
{{end}}
`))
2022-03-29 20:59:36 +00:00
}
if cfg.AllowRegistration {
m(BaseEn.Parse(`{{define "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}}`))
2022-03-29 20:59:36 +00:00
}
BaseRu = m(m(BaseEn.Clone()).Parse(ruText))
}
func localizedBaseWithWeirdBody(meta Meta) *template.Template {
t := func() *template.Template {
2022-05-18 17:18:30 +00:00
if meta.Locale() == "ru" {
2022-03-29 20:59:36 +00:00
return BaseRu
}
return BaseEn
}()
return m(m(t.Clone()).Parse(`
{{define "body"}}{{.Body}}{{end}}
{{define "title"}}{{.Title}}{{end}}
`))
2022-03-29 20:59:36 +00:00
}
type BaseData struct {
2022-03-29 20:59:36 +00:00
Meta Meta
HeadElements []string
2022-06-06 14:33:27 +00:00
HeaderLinks []HeaderLink
2022-03-29 20:59:36 +00:00
CommonScripts []string
Addr string
Title string // TODO: remove
2022-03-29 20:59:36 +00:00
Body string // TODO: remove
}
2022-06-06 14:33:27 +00:00
func (bd *BaseData) withBaseValues(meta Meta, headerLinks []HeaderLink, commonScripts []string) {
bd.Meta = meta
bd.HeaderLinks = headerLinks
bd.CommonScripts = commonScripts
}
2022-03-29 20:59:36 +00:00
// Base is a temporary wrapper around BaseEn and BaseRu, meant to facilitate the migration from qtpl.
2022-05-18 17:18:30 +00:00
// TODO: get rid of this
2022-04-01 19:51:15 +00:00
func Base(meta Meta, title, body string, headElements ...string) string {
2022-03-29 20:59:36 +00:00
var w strings.Builder
2022-04-01 19:51:15 +00:00
meta.W = &w
2022-03-29 20:59:36 +00:00
t := localizedBaseWithWeirdBody(meta)
err := t.ExecuteTemplate(&w, "page", BaseData{
2022-03-29 20:59:36 +00:00
Meta: meta,
Title: title,
HeadElements: headElements,
2022-06-06 14:33:27 +00:00
HeaderLinks: HeaderLinks,
2022-03-29 20:59:36 +00:00
CommonScripts: cfg.CommonScripts,
Body: body,
})
if err != nil {
log.Println(err)
}
return w.String()
}
2022-04-02 07:10:32 +00:00
func CopyEnRuWith(fsys fs.FS, filename, ruTranslation string) Chain {
return en(copyEnWith(fsys, filename)).
ru(template.Must(copyRuWith(fsys, filename).Parse(ruTranslation)))
}
func copyEnWith(fsys fs.FS, f string) *template.Template {
2022-04-02 07:10:32 +00:00
return m(m(BaseEn.Clone()).ParseFS(fsys, f))
}
func copyRuWith(fsys fs.FS, f string) *template.Template {
2022-04-02 07:10:32 +00:00
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 {
2022-06-06 14:33:27 +00:00
withBaseValues(meta Meta, headerLinks []HeaderLink, commonScripts []string)
}) {
2022-06-06 14:33:27 +00:00
data.withBaseValues(meta, HeaderLinks, cfg.CommonScripts)
if err := chain.Get(meta).ExecuteTemplate(meta.W, "page", data); err != nil {
log.Println(err)
}
}
2022-06-06 14:33:27 +00:00
// HeaderLinks is a list off current header links. Feel free to iterate it directly but do not modify it by yourself. Call ParseHeaderLinks if you need to set new header links.
var HeaderLinks []HeaderLink
// HeaderLink represents a header link. Header links are the links shown in the top gray bar.
type HeaderLink struct {
// Href is the URL of the link. It goes <a href="here">...</a>.
Href string
// Display is what is shown when the link is rendered. It goes <a href="...">here</a>.
Display string
}