227 lines
5.1 KiB
Go
227 lines
5.1 KiB
Go
package page
|
|
|
|
import (
|
|
. "ersteller-lib"
|
|
"fmt"
|
|
"time"
|
|
|
|
. "maragu.dev/gomponents"
|
|
. "maragu.dev/gomponents/components"
|
|
. "maragu.dev/gomponents/html"
|
|
)
|
|
|
|
const DeIndexUrl = "/de/index"
|
|
const EnIndexUrl = "/en/index"
|
|
const DefaultLanguage = En
|
|
|
|
var _texts *Texts
|
|
|
|
func CreatePage(req HtmxContext, metadata PageWebsiteMetaData, content ...Node) {
|
|
metadata.Lang = req.GetLanguage()
|
|
|
|
var contentForFunction Node
|
|
if len(content) > 0 {
|
|
contentForFunction = Div(content...)
|
|
} else if len(content) == 0 {
|
|
contentForFunction = Div()
|
|
} else if len(content) == 1 {
|
|
contentForFunction = content[0]
|
|
}
|
|
|
|
styles := []string{
|
|
"/static/styles.css",
|
|
}
|
|
for _, src := range metadata.StyleSrcs {
|
|
styles = append(styles, src)
|
|
}
|
|
|
|
scripts := []string{
|
|
"/static/scripts/language-select.js",
|
|
"/static/htmx.js",
|
|
}
|
|
for _, src := range metadata.ScriptSrcs {
|
|
scripts = append(scripts, src)
|
|
}
|
|
|
|
page := HTML5(HTML5Props{
|
|
Title: "White Label App " + metadata.Title.From(req),
|
|
Language: string(metadata.Lang),
|
|
Description: metadata.Description.From(req),
|
|
Head: []Node{
|
|
Map(styles, func(s string) Node {
|
|
return Link(Rel("stylesheet"), Href(s))
|
|
}),
|
|
Map(scripts, func(s string) Node {
|
|
return Script(Type("text/javascript"), Src(s))
|
|
}),
|
|
addLanguageSelectScript(metadata),
|
|
},
|
|
Body: []Node{
|
|
Header(Class("header"),
|
|
Div(Class("header-content"),
|
|
Div(Class("logo"),
|
|
Span(Class("logo-icon"), Text("🚀")),
|
|
Span(Class("logo-text"), Text("White Label App")),
|
|
),
|
|
getNav(req, metadata),
|
|
getLanguageSwitcher(req, metadata),
|
|
),
|
|
),
|
|
Div(Class("container"),
|
|
contentForFunction,
|
|
),
|
|
Footer(Class("footer"),
|
|
Div(Class("footer-menu"), Aria("label", "Footer Menu"),
|
|
getFooterMenu(req, metadata),
|
|
),
|
|
P(Class("footer-disclaimer"), Text(getTexts().disclaimer.From(req))),
|
|
P(Text(getTexts().getCopyright(req.GetLanguage()))),
|
|
),
|
|
},
|
|
})
|
|
req.Render(page)
|
|
}
|
|
|
|
func addLanguageSelectScript(metadata PageWebsiteMetaData) Node {
|
|
script := InlineTemplate(`
|
|
(function() {
|
|
const langs = {
|
|
de: "$.DeUrl$",
|
|
en: "$.EnUrl$",
|
|
};
|
|
const currentLang = "$.CurrentLang$";
|
|
const defaultLang = "$.DefaultLang$";
|
|
selectWebsiteLanguage(currentLang, langs, defaultLang);
|
|
})();`, struct {
|
|
CurrentLang string
|
|
DeUrl string
|
|
EnUrl string
|
|
DefaultLang string
|
|
}{
|
|
CurrentLang: string(metadata.Lang),
|
|
DeUrl: DeIndexUrl,
|
|
EnUrl: EnIndexUrl,
|
|
DefaultLang: string(DefaultLanguage),
|
|
})
|
|
return Script(Type("text/javascript"), Raw(script))
|
|
}
|
|
|
|
func getNav(c HtmxContext, metadata PageWebsiteMetaData) Node {
|
|
return Nav(Class("nav"), Aria("label", "Main Menu"),
|
|
Map(metadata.NavItems, func(path ActivePath) Node {
|
|
return createNavItem(c, path)
|
|
}),
|
|
)
|
|
}
|
|
|
|
func createNavItem(c HtmxContext, activePath ActivePath) Node {
|
|
isActive := activePath.IsActive(c)
|
|
return A(
|
|
Href(activePath.GetPath(c.GetLanguage())),
|
|
Text(activePath.From(c)),
|
|
If(isActive, Attr("aria-current", "page")),
|
|
If(isActive, Class("selected")),
|
|
)
|
|
}
|
|
|
|
func getLanguageSwitcher(c HtmxContext, metadata PageWebsiteMetaData) Node {
|
|
currentLang := c.GetLanguage()
|
|
|
|
var currentRoute HtmxRoute
|
|
for _, route := range c.GetAllRoutes() {
|
|
if route.IsCurrentRoute(c) {
|
|
currentRoute = route
|
|
break
|
|
}
|
|
}
|
|
|
|
return Div(Class("language-switcher"),
|
|
createLanguageButton(En, currentLang, currentRoute, c),
|
|
createLanguageButton(De, currentLang, currentRoute, c),
|
|
)
|
|
}
|
|
|
|
func getFooterMenu(c HtmxContext, metadata PageWebsiteMetaData) Node {
|
|
lang := c.GetLanguage()
|
|
return Div(
|
|
Map(metadata.FooterNavItems, func(path ActivePath) Node {
|
|
return Span(
|
|
A(Href(path.GetPath(lang)), Class("footer-link"), Text(path.From(c))),
|
|
)
|
|
}),
|
|
)
|
|
}
|
|
|
|
func createLanguageButton(lang Language, currentLang Language, route HtmxRoute, c HtmxContext) Node {
|
|
isActive := lang == currentLang
|
|
var href string
|
|
|
|
if route != nil {
|
|
href = route.ToUrlFromContext(c, lang)
|
|
} else {
|
|
// Fallback to index page if no active path found
|
|
if lang == En {
|
|
href = EnIndexUrl
|
|
} else {
|
|
href = DeIndexUrl
|
|
}
|
|
}
|
|
|
|
var langText string
|
|
if lang == En {
|
|
langText = "EN"
|
|
} else {
|
|
langText = "DE"
|
|
}
|
|
|
|
// Combine classes properly
|
|
var classes string
|
|
if isActive {
|
|
classes = "language-button active"
|
|
} else {
|
|
classes = "language-button inactive"
|
|
}
|
|
|
|
return A(
|
|
Href(href),
|
|
Text(langText),
|
|
Class(classes),
|
|
)
|
|
}
|
|
|
|
type Texts struct {
|
|
disclaimer I18nText
|
|
copyright I18nText
|
|
}
|
|
|
|
func NewTexts() *Texts {
|
|
return &Texts{
|
|
disclaimer: NewI18nText(map[Language]string{
|
|
De: "Dies ist eine White-Label-Vorlage. Passen Sie den Inhalt an Ihre Bedürfnisse an.",
|
|
En: "This is a white label template. Customize the content to fit your needs.",
|
|
}),
|
|
copyright: NewI18nText(map[Language]string{
|
|
De: "© 2020 - $Year$ White Label App. Alle Rechte vorbehalten.",
|
|
En: "© 2020 - $Year$ White Label App. All rights reserved.",
|
|
}),
|
|
}
|
|
}
|
|
|
|
func (t *Texts) getCopyright(lang Language) string {
|
|
currentYear := fmt.Sprint(time.Now().Year())
|
|
text := t.copyright.FromLang(lang)
|
|
return InlineTemplate(text, struct {
|
|
Year string
|
|
}{
|
|
Year: currentYear,
|
|
})
|
|
}
|
|
|
|
func getTexts() *Texts {
|
|
if _texts != nil {
|
|
return _texts
|
|
}
|
|
_texts = NewTexts()
|
|
return _texts
|
|
}
|