mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2024-12-13 14:00:25 +00:00
738948f752
A selection of great commit messages: - "Safari is a great browser!" -- No one If in doubt, just stick overflow: hidden onto it. No, seriously, I just added it in Safari devtools and it worked. You'd think Apple has a competent team, right? - Bully Safari into not triggering the Show status bar menu item If in doubt, just bully Safari. What is Safari gonna do? Tell Steve Jobs?
166 lines
4.7 KiB
Go
166 lines
4.7 KiB
Go
// Package viewutil provides utilities and common templates for views across all packages.
|
|
package viewutil
|
|
|
|
import (
|
|
"embed"
|
|
"fmt"
|
|
"io/fs"
|
|
"log"
|
|
"strings"
|
|
"text/template" // TODO: save the world
|
|
|
|
"github.com/bouncepaw/mycorrhiza/cfg"
|
|
"github.com/bouncepaw/mycorrhiza/util"
|
|
)
|
|
|
|
var (
|
|
//go:embed *.html
|
|
fsys embed.FS
|
|
BaseEn *template.Template
|
|
BaseRu *template.Template
|
|
m = template.Must
|
|
)
|
|
|
|
const ruText = `
|
|
{{define "search by title"}}Поиск по названию{{end}}
|
|
{{define "login"}}Войти{{end}}
|
|
{{define "register"}}Регистрация{{end}}
|
|
{{define "confirm"}}Подтвердить{{end}}
|
|
{{define "cancel"}}Отмена{{end}}
|
|
{{define "save"}}Сохранить{{end}}
|
|
{{define "error"}}Ошибка{{end}}
|
|
{{define "delete"}}Удалить{{end}}
|
|
`
|
|
|
|
func Init() {
|
|
dataText := fmt.Sprintf(`
|
|
{{define "wiki name"}}%s{{end}}
|
|
{{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 },
|
|
}).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}}
|
|
`))
|
|
}
|
|
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}}`))
|
|
}
|
|
BaseRu = m(m(BaseEn.Clone()).Parse(ruText))
|
|
}
|
|
|
|
func localizedBaseWithWeirdBody(meta Meta) *template.Template {
|
|
t := func() *template.Template {
|
|
if meta.Locale() == "ru" {
|
|
return BaseRu
|
|
}
|
|
return BaseEn
|
|
}()
|
|
return m(m(t.Clone()).Parse(`
|
|
{{define "body"}}{{.Body}}{{end}}
|
|
{{define "title"}}{{.Title}}{{end}}
|
|
`))
|
|
}
|
|
|
|
type BaseData struct {
|
|
Meta Meta
|
|
HeadElements []string
|
|
HeaderLinks []HeaderLink
|
|
CommonScripts []string
|
|
EditScripts []string
|
|
Addr string
|
|
Title string // TODO: remove
|
|
Body string // TODO: remove
|
|
BodyAttributes map[string]string
|
|
}
|
|
|
|
func (bd *BaseData) withBaseValues(meta Meta, headerLinks []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.
|
|
// TODO: get rid of this
|
|
func Base(meta Meta, title, body string, bodyAttributes map[string]string, headElements ...string) string {
|
|
var w strings.Builder
|
|
meta.W = &w
|
|
t := localizedBaseWithWeirdBody(meta)
|
|
err := t.ExecuteTemplate(&w, "page", BaseData{
|
|
Meta: meta,
|
|
Title: title,
|
|
HeadElements: headElements,
|
|
HeaderLinks: HeaderLinks,
|
|
CommonScripts: cfg.CommonScripts,
|
|
EditScripts: cfg.EditScripts,
|
|
Body: body,
|
|
BodyAttributes: bodyAttributes,
|
|
})
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
return w.String()
|
|
}
|
|
|
|
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 {
|
|
return m(m(BaseEn.Clone()).ParseFS(fsys, f))
|
|
}
|
|
|
|
func copyRuWith(fsys fs.FS, f string) *template.Template {
|
|
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 []HeaderLink, commonScripts []string)
|
|
}) {
|
|
data.withBaseValues(meta, HeaderLinks, cfg.CommonScripts)
|
|
if err := chain.Get(meta).ExecuteTemplate(meta.W, "page", data); err != nil {
|
|
log.Println(err)
|
|
}
|
|
}
|
|
|
|
// 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
|
|
}
|