internal/builder/page.templ (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | package builder
import (
"net/url"
"website/internal/config"
)
type PageSettings struct {
Title string
Path string
TitleAttrs templ.Attributes
BodyAttrs templ.Attributes
}
func extendClasses(cs string, attrs templ.Attributes) string {
if extras, exists := attrs["class"]; exists {
return templ.Classes(cs, extras).String()
} else {
return cs
}
}
templ menuItem(item config.MenuItem) {
<a
href={ templ.SafeURL(item.URL.String()) }
if item.URL.IsAbs() {
target="_blank"
}
>{ item.Name }</a>
}
templ page(site config.Config, page PageSettings) {
<!DOCTYPE html>
<html lang={ site.DefaultLanguage }>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>{ page.Title }</title>
<link rel="alternate" type="application/atom+xml" title={ site.Title } href="/atom.xml"/>
@style(css)
</head>
<body { page.BodyAttrs... }>
<a class="skip" href="#main">Skip to main content</a>
<header>
<h2>
<a href="/" class={ extendClasses("title p-name", page.TitleAttrs) } { page.TitleAttrs... }>{ site.Title }</a>
</h2>
<nav>
for _, item := range site.Menus["main"] {
@menuItem(item)
}
</nav>
</header>
<main id="main">
{ children... }
</main>
<footer>
Content is
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.
<a href="https://git.alanpearce.eu/website/">Site source code</a> is
<a href="https://opensource.org/licenses/MIT">MIT</a>
</footer>
@counter(page.Path, page.Title)
if site.InjectLiveReload {
<script defer>
new EventSource("/_/reload").onmessage = event => {
console.log("got message", event)
window.location.reload()
};
</script>
}
</body>
</html>
}
func mkURL(path string, title string) string {
u, err := url.Parse("https://alanpearce-eu.goatcounter.com/count")
if err != nil {
panic(err)
}
q := u.Query()
q.Add("p", path)
q.Add("t", title)
u.RawQuery = q.Encode()
return u.String()
}
templ counter(path string, title string) {
<script data-goatcounter="https://alanpearce-eu.goatcounter.com/count" async src="https://gc.zgo.at/count.v4.js" crossorigin="anonymous" integrity="sha384-nRw6qfbWyJha9LhsOtSb2YJDyZdKvvCFh0fJYlkquSFjUxp9FVNugbfy8q1jdxI+"></script>
<noscript>
<img src={ string(templ.URL(mkURL(path, title))) }/>
</noscript>
}
func style(css string) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) {
_, err = io.WriteString(w, "<style>\n"+css+"\n</style>")
return
})
}
|