cerrado @ c6f77e08b8a26ec740f3121edbb7a9d06c04ce20

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.
  1diff --git a/pkg/handler/router.go b/pkg/handler/router.go
  2index cb5d6f54dfbf444aa0830337c9f9044067d9c16b..1fbc4e3f90bc3304bf82c26084a06ddf756df5dc 100644
  3--- a/pkg/handler/router.go
  4+++ b/pkg/handler/router.go
  5@@ -55,7 +55,11 @@ 		mux.AddMiddleware(ext.DisableAuthentication)
  6 	}
  7 
  8 	mux.HandleFunc("/static/{file}", staticHandler)
  9-	mux.HandleFunc(fmt.Sprintf("/static/theme%s.css", templates.Slug), cssStaticHandler) // add slug so css file can be cached forever.
 10+	// add slug and session so css file can be cached forever.
 11+	// Slug follow commit id, which is update every new version
 12+	// Session is update every time server restarts, this allows the css to be
 13+	// cached forever but refresh if the admin updates the server configuration.
 14+	mux.HandleFunc(fmt.Sprintf("/static/theme.%s%s.css", templates.Session, templates.Slug), cssStaticHandler)
 15 	mux.HandleFunc("/{name}/about/{$}", gitHandler.About)
 16 	mux.HandleFunc("/{name}", gitHandler.Multiplex)
 17 	mux.HandleFunc("/{name}/{rest...}", gitHandler.Multiplex)
 18diff --git a/templates/base.qtpl b/templates/base.qtpl
 19index 1dddb57bb0f0f60829259fc2eb60561c823a5b6f..6ff3d5340196e906267f25a52d87f3620da8ab0b 100644
 20--- a/templates/base.qtpl
 21+++ b/templates/base.qtpl
 22@@ -1,11 +1,28 @@
 23 This is a base page template. All the other template pages implement this interface.
 24 
 25 {% import "context" %}
 26+{% import "crypto/rand" %}
 27+{% import "encoding/hex" %}
 28 {% import "strconv" %}
 29 {% import "time" %}
 30 
 31-{% code 
 32+{% code
 33+
 34  var Slug = ""
 35+ var Session = ""
 36+
 37+ func init() {
 38+    Session =  hex.EncodeToString(generateSmallTimeID())
 39+}
 40+
 41+func generateSmallTimeID() []byte {
 42+    b := make([]byte, 4)
 43+    _, err := rand.Read(b)
 44+    if err != nil {
 45+        panic(err)
 46+    }
 47+    return b
 48+}
 49 %}
 50 
 51 {% interface
 52@@ -58,9 +75,9 @@ <html lang="en" data-bs-theme="light">
 53   <head>
 54     <meta charset="utf-8">
 55     <link rel="icon" href="data:,">
 56-    <title>{%= p.Title(ctx) %}</title> 
 57+    <title>{%= p.Title(ctx) %}</title>
 58     <link rel="stylesheet" href="/static/main{%s Slug %}.css">
 59-    <link rel="stylesheet" href="/static/theme{%s Slug %}.css">
 60+    <link rel="stylesheet" href="/static/theme.{%s Session %}{%s Slug %}.css">
 61     <html data-bs-theme="dark">
 62     <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
 63     <meta name="viewport" content="width=device-width, initial-scale=1" />
 64diff --git a/templates/base.qtpl.go b/templates/base.qtpl.go
 65index 3c4d8a94cc1649c5efd739976e21c045f8582db4..db8afecb01de33a8fec5beb9d2a6796e4d6662ed 100644
 66--- a/templates/base.qtpl.go
 67+++ b/templates/base.qtpl.go
 68@@ -11,57 +11,77 @@ //line templates/base.qtpl:3
 69 import "context"
 70 
 71 //line templates/base.qtpl:4
 72-import "strconv"
 73+import "crypto/rand"
 74 
 75 //line templates/base.qtpl:5
 76-import "time"
 77+import "encoding/hex"
 78+
 79+//line templates/base.qtpl:6
 80+import "strconv"
 81 
 82 //line templates/base.qtpl:7
 83+import "time"
 84+
 85+//line templates/base.qtpl:9
 86 import (
 87 	qtio422016 "io"
 88 
 89 	qt422016 "github.com/valyala/quicktemplate"
 90 )
 91 
 92-//line templates/base.qtpl:7
 93+//line templates/base.qtpl:9
 94 var (
 95 	_ = qtio422016.Copy
 96 	_ = qt422016.AcquireByteBuffer
 97 )
 98 
 99-//line templates/base.qtpl:8
100+//line templates/base.qtpl:11
101 var Slug = ""
102+var Session = ""
103 
104-//line templates/base.qtpl:12
105+func init() {
106+	Session = hex.EncodeToString(generateSmallTimeID())
107+}
108+
109+func generateSmallTimeID() []byte {
110+	b := make([]byte, 4)
111+	_, err := rand.Read(b)
112+	if err != nil {
113+		panic(err)
114+	}
115+	return b
116+}
117+
118+//line templates/base.qtpl:29
119 type Page interface {
120-//line templates/base.qtpl:12
121+//line templates/base.qtpl:29
122 	Title(ctx context.Context) string
123-//line templates/base.qtpl:12
124+//line templates/base.qtpl:29
125 	StreamTitle(qw422016 *qt422016.Writer, ctx context.Context)
126-//line templates/base.qtpl:12
127+//line templates/base.qtpl:29
128 	WriteTitle(qq422016 qtio422016.Writer, ctx context.Context)
129-//line templates/base.qtpl:12
130+//line templates/base.qtpl:29
131 	Content(ctx context.Context) string
132-//line templates/base.qtpl:12
133+//line templates/base.qtpl:29
134 	StreamContent(qw422016 *qt422016.Writer, ctx context.Context)
135-//line templates/base.qtpl:12
136+//line templates/base.qtpl:29
137 	WriteContent(qq422016 qtio422016.Writer, ctx context.Context)
138-//line templates/base.qtpl:12
139+//line templates/base.qtpl:29
140 	Script(ctx context.Context) string
141-//line templates/base.qtpl:12
142+//line templates/base.qtpl:29
143 	StreamScript(qw422016 *qt422016.Writer, ctx context.Context)
144-//line templates/base.qtpl:12
145+//line templates/base.qtpl:29
146 	WriteScript(qq422016 qtio422016.Writer, ctx context.Context)
147-//line templates/base.qtpl:12
148+//line templates/base.qtpl:29
149 	Navbar(ctx context.Context) string
150-//line templates/base.qtpl:12
151+//line templates/base.qtpl:29
152 	StreamNavbar(qw422016 *qt422016.Writer, ctx context.Context)
153-//line templates/base.qtpl:12
154+//line templates/base.qtpl:29
155 	WriteNavbar(qq422016 qtio422016.Writer, ctx context.Context)
156-//line templates/base.qtpl:12
157+//line templates/base.qtpl:29
158 }
159 
160-//line templates/base.qtpl:21
161+//line templates/base.qtpl:38
162 func FromUInttoString(u *uint) string {
163 	if u != nil {
164 		return strconv.FormatUint(uint64(*u), 10)
165@@ -69,23 +89,23 @@ 	}
166 	return ""
167 }
168 
169-//line templates/base.qtpl:31
170+//line templates/base.qtpl:48
171 func TimeFormat(t time.Time) string {
172 	return t.Format("02.01.2006")
173 }
174 
175-//line templates/base.qtpl:36
176+//line templates/base.qtpl:53
177 func Ignore[T any](v T, _ error) T {
178 	return v
179 }
180 
181-//line templates/base.qtpl:42
182+//line templates/base.qtpl:59
183 func IsAuthenticationDisabled(ctx context.Context) bool {
184 	t, ok := ctx.Value("disableAuthentication").(bool)
185 	return ok && t
186 }
187 
188-//line templates/base.qtpl:48
189+//line templates/base.qtpl:65
190 func IsLoggedIn(ctx context.Context) bool {
191 	t, ok := ctx.Value("logged").(bool)
192 	return ok && t
193@@ -93,9 +113,9 @@ }
194 
195 // Page prints a page implementing Page interface.
196 
197-//line templates/base.qtpl:55
198+//line templates/base.qtpl:72
199 func StreamPageTemplate(qw422016 *qt422016.Writer, p Page, ctx context.Context) {
200-//line templates/base.qtpl:55
201+//line templates/base.qtpl:72
202 	qw422016.N().S(`
203 <!DOCTYPE html>
204 <html lang="en" data-bs-theme="light">
205@@ -103,19 +123,21 @@   <head>
206     <meta charset="utf-8">
207     <link rel="icon" href="data:,">
208     <title>`)
209-//line templates/base.qtpl:61
210+//line templates/base.qtpl:78
211 	p.StreamTitle(qw422016, ctx)
212-//line templates/base.qtpl:61
213-	qw422016.N().S(`</title> 
214+//line templates/base.qtpl:78
215+	qw422016.N().S(`</title>
216     <link rel="stylesheet" href="/static/main`)
217-//line templates/base.qtpl:62
218+//line templates/base.qtpl:79
219 	qw422016.E().S(Slug)
220-//line templates/base.qtpl:62
221+//line templates/base.qtpl:79
222 	qw422016.N().S(`.css">
223-    <link rel="stylesheet" href="/static/theme`)
224-//line templates/base.qtpl:63
225+    <link rel="stylesheet" href="/static/theme.`)
226+//line templates/base.qtpl:80
227+	qw422016.E().S(Session)
228+//line templates/base.qtpl:80
229 	qw422016.E().S(Slug)
230-//line templates/base.qtpl:63
231+//line templates/base.qtpl:80
232 	qw422016.N().S(`.css">
233     <html data-bs-theme="dark">
234     <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
235@@ -123,53 +145,53 @@     <meta name="viewport" content="width=device-width, initial-scale=1" />
236   </head>
237   <body>
238     `)
239-//line templates/base.qtpl:69
240+//line templates/base.qtpl:86
241 	p.StreamNavbar(qw422016, ctx)
242-//line templates/base.qtpl:69
243+//line templates/base.qtpl:86
244 	qw422016.N().S(`
245     <div class="container">
246       `)
247-//line templates/base.qtpl:71
248+//line templates/base.qtpl:88
249 	p.StreamContent(qw422016, ctx)
250-//line templates/base.qtpl:71
251+//line templates/base.qtpl:88
252 	qw422016.N().S(`
253     </div>
254   </body>
255   `)
256-//line templates/base.qtpl:74
257+//line templates/base.qtpl:91
258 	p.StreamScript(qw422016, ctx)
259-//line templates/base.qtpl:74
260+//line templates/base.qtpl:91
261 	qw422016.N().S(`
262   <script>
263   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);
264   </script>
265 </html>
266 `)
267-//line templates/base.qtpl:79
268+//line templates/base.qtpl:96
269 }
270 
271-//line templates/base.qtpl:79
272+//line templates/base.qtpl:96
273 func WritePageTemplate(qq422016 qtio422016.Writer, p Page, ctx context.Context) {
274-//line templates/base.qtpl:79
275+//line templates/base.qtpl:96
276 	qw422016 := qt422016.AcquireWriter(qq422016)
277-//line templates/base.qtpl:79
278+//line templates/base.qtpl:96
279 	StreamPageTemplate(qw422016, p, ctx)
280-//line templates/base.qtpl:79
281+//line templates/base.qtpl:96
282 	qt422016.ReleaseWriter(qw422016)
283-//line templates/base.qtpl:79
284+//line templates/base.qtpl:96
285 }
286 
287-//line templates/base.qtpl:79
288+//line templates/base.qtpl:96
289 func PageTemplate(p Page, ctx context.Context) string {
290-//line templates/base.qtpl:79
291+//line templates/base.qtpl:96
292 	qb422016 := qt422016.AcquireByteBuffer()
293-//line templates/base.qtpl:79
294+//line templates/base.qtpl:96
295 	WritePageTemplate(qb422016, p, ctx)
296-//line templates/base.qtpl:79
297+//line templates/base.qtpl:96
298 	qs422016 := string(qb422016.B)
299-//line templates/base.qtpl:79
300+//line templates/base.qtpl:96
301 	qt422016.ReleaseByteBuffer(qb422016)
302-//line templates/base.qtpl:79
303+//line templates/base.qtpl:96
304 	return qs422016
305-//line templates/base.qtpl:79
306+//line templates/base.qtpl:96
307 }