aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel A. Giovanini <mail@gabrielgio.me>2025-11-01 18:34:04 +0100
committerGabriel A. Giovanini <mail@gabrielgio.me>2025-11-01 18:34:04 +0100
commitc6f77e08b8a26ec740f3121edbb7a9d06c04ce20 (patch)
tree7155f98f89a8d7ba310416ca13170b3af172a509
parent49fc8733129028ff4a3537b9eb20f548f0e3e9e6 (diff)
downloadcerrado-c6f77e08b8a26ec740f3121edbb7a9d06c04ce20.tar.gz
cerrado-c6f77e08b8a26ec740f3121edbb7a9d06c04ce20.tar.bz2
cerrado-c6f77e08b8a26ec740f3121edbb7a9d06c04ce20.zip
feat: Add session variable
This will allow the css to be refreshed once the server is restarted. This allows the admin to update the theme configuration and have it reflected in the browser.
-rw-r--r--pkg/handler/router.go6
-rw-r--r--templates/base.qtpl23
-rw-r--r--templates/base.qtpl.go126
3 files changed, 99 insertions, 56 deletions
diff --git a/pkg/handler/router.go b/pkg/handler/router.go
index cb5d6f5..1fbc4e3 100644
--- a/pkg/handler/router.go
+++ b/pkg/handler/router.go
@@ -55,7 +55,11 @@ func MountHandler(
}
mux.HandleFunc("/static/{file}", staticHandler)
- mux.HandleFunc(fmt.Sprintf("/static/theme%s.css", templates.Slug), cssStaticHandler) // add slug so css file can be cached forever.
+ // add slug and session so css file can be cached forever.
+ // Slug follow commit id, which is update every new version
+ // Session is update every time server restarts, this allows the css to be
+ // cached forever but refresh if the admin updates the server configuration.
+ mux.HandleFunc(fmt.Sprintf("/static/theme.%s%s.css", templates.Session, templates.Slug), cssStaticHandler)
mux.HandleFunc("/{name}/about/{$}", gitHandler.About)
mux.HandleFunc("/{name}", gitHandler.Multiplex)
mux.HandleFunc("/{name}/{rest...}", gitHandler.Multiplex)
diff --git a/templates/base.qtpl b/templates/base.qtpl
index 1dddb57..6ff3d53 100644
--- a/templates/base.qtpl
+++ b/templates/base.qtpl
@@ -1,11 +1,28 @@
This is a base page template. All the other template pages implement this interface.
{% import "context" %}
+{% import "crypto/rand" %}
+{% import "encoding/hex" %}
{% import "strconv" %}
{% import "time" %}
-{% code
+{% code
+
var Slug = ""
+ var Session = ""
+
+ func init() {
+ Session = hex.EncodeToString(generateSmallTimeID())
+}
+
+func generateSmallTimeID() []byte {
+ b := make([]byte, 4)
+ _, err := rand.Read(b)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
%}
{% interface
@@ -58,9 +75,9 @@ Page prints a page implementing Page interface.
<head>
<meta charset="utf-8">
<link rel="icon" href="data:,">
- <title>{%= p.Title(ctx) %}</title>
+ <title>{%= p.Title(ctx) %}</title>
<link rel="stylesheet" href="/static/main{%s Slug %}.css">
- <link rel="stylesheet" href="/static/theme{%s Slug %}.css">
+ <link rel="stylesheet" href="/static/theme.{%s Session %}{%s Slug %}.css">
<html data-bs-theme="dark">
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1" />
diff --git a/templates/base.qtpl.go b/templates/base.qtpl.go
index 3c4d8a9..db8afec 100644
--- a/templates/base.qtpl.go
+++ b/templates/base.qtpl.go
@@ -11,57 +11,77 @@ package templates
import "context"
//line templates/base.qtpl:4
-import "strconv"
+import "crypto/rand"
//line templates/base.qtpl:5
-import "time"
+import "encoding/hex"
+
+//line templates/base.qtpl:6
+import "strconv"
//line templates/base.qtpl:7
+import "time"
+
+//line templates/base.qtpl:9
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
-//line templates/base.qtpl:7
+//line templates/base.qtpl:9
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
-//line templates/base.qtpl:8
+//line templates/base.qtpl:11
var Slug = ""
+var Session = ""
-//line templates/base.qtpl:12
+func init() {
+ Session = hex.EncodeToString(generateSmallTimeID())
+}
+
+func generateSmallTimeID() []byte {
+ b := make([]byte, 4)
+ _, err := rand.Read(b)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+//line templates/base.qtpl:29
type Page interface {
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
Title(ctx context.Context) string
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
StreamTitle(qw422016 *qt422016.Writer, ctx context.Context)
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
WriteTitle(qq422016 qtio422016.Writer, ctx context.Context)
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
Content(ctx context.Context) string
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
StreamContent(qw422016 *qt422016.Writer, ctx context.Context)
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
WriteContent(qq422016 qtio422016.Writer, ctx context.Context)
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
Script(ctx context.Context) string
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
StreamScript(qw422016 *qt422016.Writer, ctx context.Context)
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
WriteScript(qq422016 qtio422016.Writer, ctx context.Context)
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
Navbar(ctx context.Context) string
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
StreamNavbar(qw422016 *qt422016.Writer, ctx context.Context)
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
WriteNavbar(qq422016 qtio422016.Writer, ctx context.Context)
-//line templates/base.qtpl:12
+//line templates/base.qtpl:29
}
-//line templates/base.qtpl:21
+//line templates/base.qtpl:38
func FromUInttoString(u *uint) string {
if u != nil {
return strconv.FormatUint(uint64(*u), 10)
@@ -69,23 +89,23 @@ func FromUInttoString(u *uint) string {
return ""
}
-//line templates/base.qtpl:31
+//line templates/base.qtpl:48
func TimeFormat(t time.Time) string {
return t.Format("02.01.2006")
}
-//line templates/base.qtpl:36
+//line templates/base.qtpl:53
func Ignore[T any](v T, _ error) T {
return v
}
-//line templates/base.qtpl:42
+//line templates/base.qtpl:59
func IsAuthenticationDisabled(ctx context.Context) bool {
t, ok := ctx.Value("disableAuthentication").(bool)
return ok && t
}
-//line templates/base.qtpl:48
+//line templates/base.qtpl:65
func IsLoggedIn(ctx context.Context) bool {
t, ok := ctx.Value("logged").(bool)
return ok && t
@@ -93,9 +113,9 @@ func IsLoggedIn(ctx context.Context) bool {
// Page prints a page implementing Page interface.
-//line templates/base.qtpl:55
+//line templates/base.qtpl:72
func StreamPageTemplate(qw422016 *qt422016.Writer, p Page, ctx context.Context) {
-//line templates/base.qtpl:55
+//line templates/base.qtpl:72
qw422016.N().S(`
<!DOCTYPE html>
<html lang="en" data-bs-theme="light">
@@ -103,19 +123,21 @@ func StreamPageTemplate(qw422016 *qt422016.Writer, p Page, ctx context.Context)
<meta charset="utf-8">
<link rel="icon" href="data:,">
<title>`)
-//line templates/base.qtpl:61
+//line templates/base.qtpl:78
p.StreamTitle(qw422016, ctx)
-//line templates/base.qtpl:61
- qw422016.N().S(`</title>
+//line templates/base.qtpl:78
+ qw422016.N().S(`</title>
<link rel="stylesheet" href="/static/main`)
-//line templates/base.qtpl:62
+//line templates/base.qtpl:79
qw422016.E().S(Slug)
-//line templates/base.qtpl:62
+//line templates/base.qtpl:79
qw422016.N().S(`.css">
- <link rel="stylesheet" href="/static/theme`)
-//line templates/base.qtpl:63
+ <link rel="stylesheet" href="/static/theme.`)
+//line templates/base.qtpl:80
+ qw422016.E().S(Session)
+//line templates/base.qtpl:80
qw422016.E().S(Slug)
-//line templates/base.qtpl:63
+//line templates/base.qtpl:80
qw422016.N().S(`.css">
<html data-bs-theme="dark">
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
@@ -123,53 +145,53 @@ func StreamPageTemplate(qw422016 *qt422016.Writer, p Page, ctx context.Context)
</head>
<body>
`)
-//line templates/base.qtpl:69
+//line templates/base.qtpl:86
p.StreamNavbar(qw422016, ctx)
-//line templates/base.qtpl:69
+//line templates/base.qtpl:86
qw422016.N().S(`
<div class="container">
`)
-//line templates/base.qtpl:71
+//line templates/base.qtpl:88
p.StreamContent(qw422016, ctx)
-//line templates/base.qtpl:71
+//line templates/base.qtpl:88
qw422016.N().S(`
</div>
</body>
`)
-//line templates/base.qtpl:74
+//line templates/base.qtpl:91
p.StreamScript(qw422016, ctx)
-//line templates/base.qtpl:74
+//line templates/base.qtpl:91
qw422016.N().S(`
<script>
function a(){const e=window.matchMedia("(prefers-color-scheme: dark)").matches;document.documentElement.setAttribute("data-bs-theme",e?"dark":"light")}a(),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",a);
</script>
</html>
`)
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
}
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
func WritePageTemplate(qq422016 qtio422016.Writer, p Page, ctx context.Context) {
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
qw422016 := qt422016.AcquireWriter(qq422016)
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
StreamPageTemplate(qw422016, p, ctx)
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
qt422016.ReleaseWriter(qw422016)
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
}
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
func PageTemplate(p Page, ctx context.Context) string {
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
qb422016 := qt422016.AcquireByteBuffer()
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
WritePageTemplate(qb422016, p, ctx)
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
qs422016 := string(qb422016.B)
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
qt422016.ReleaseByteBuffer(qb422016)
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
return qs422016
-//line templates/base.qtpl:79
+//line templates/base.qtpl:96
}