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"
2022-03-29 21:11:34 +00:00
"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"
2022-03-29 21:11:34 +00:00
"text/template" // TODO: save the world
2022-03-29 20:59:36 +00:00
)
var (
2022-03-29 21:11:34 +00:00
//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 } }
2022-08-02 09:29:25 +00:00
{ { 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 )
2022-03-29 21:11:34 +00:00
BaseEn = m ( m ( template . New ( "" ) .
Funcs ( template . FuncMap {
"beautifulName" : util . BeautifulName ,
2022-04-23 20:35:36 +00:00
"inc" : func ( i int ) int { return i + 1 } ,
2022-04-02 07:10:32 +00:00
} ) . ParseFS ( fsys , "base.html" ) ) .
2022-03-29 21:11:34 +00:00
Parse ( dataText ) )
2022-04-29 09:52:31 +00:00
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
}
2022-04-29 09:52:31 +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
} ( )
2022-04-01 21:35:40 +00:00
return m ( m ( t . Clone ( ) ) . Parse ( `
{ { define "body" } } { { . Body } } { { end } }
{ { define "title" } } { { . Title } } { { end } }
` ) )
2022-03-29 20:59:36 +00:00
}
2022-04-01 20:52:56 +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
2022-04-23 18:53:15 +00:00
Addr string
2022-04-01 21:35:40 +00:00
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 ) {
2022-05-18 16:46:01 +00:00
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 )
2022-04-01 20:52:56 +00:00
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
2022-05-18 16:58:24 +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 ) )
}
2022-05-18 16:58:24 +00:00
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 ) )
}
2022-05-18 16:46:01 +00:00
// 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-05-18 16:46:01 +00:00
} ) {
2022-06-06 14:33:27 +00:00
data . withBaseValues ( meta , HeaderLinks , cfg . CommonScripts )
2022-05-18 16:46:01 +00:00
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
}