cerrado @ 49fc8733129028ff4a3537b9eb20f548f0e3e9e6

feat: Add slug to css so we can cache it forever
  1diff --git a/pkg/handler/router.go b/pkg/handler/router.go
  2index bc81350d19a5296cae5d8da058bac29a69bff693..cb5d6f54dfbf444aa0830337c9f9044067d9c16b 100644
  3--- a/pkg/handler/router.go
  4+++ b/pkg/handler/router.go
  5@@ -1,6 +1,7 @@
  6 package handler
  7 
  8 import (
  9+	"fmt"
 10 	"net/http"
 11 
 12 	serverconfig "git.gabrielgio.me/cerrado/pkg/config"
 13@@ -10,6 +11,7 @@ 	"git.gabrielgio.me/cerrado/pkg/handler/auth"
 14 	"git.gabrielgio.me/cerrado/pkg/handler/git"
 15 	"git.gabrielgio.me/cerrado/pkg/handler/static"
 16 	"git.gabrielgio.me/cerrado/pkg/service"
 17+	"git.gabrielgio.me/cerrado/templates"
 18 )
 19 
 20 // Mount handler gets the requires service and repository to build the handlers
 21@@ -53,7 +55,7 @@ 		mux.AddMiddleware(ext.DisableAuthentication)
 22 	}
 23 
 24 	mux.HandleFunc("/static/{file}", staticHandler)
 25-	mux.HandleFunc("/static/theme", cssStaticHandler)
 26+	mux.HandleFunc(fmt.Sprintf("/static/theme%s.css", templates.Slug), cssStaticHandler) // add slug so css file can be cached forever.
 27 	mux.HandleFunc("/{name}/about/{$}", gitHandler.About)
 28 	mux.HandleFunc("/{name}", gitHandler.Multiplex)
 29 	mux.HandleFunc("/{name}/{rest...}", gitHandler.Multiplex)
 30diff --git a/pkg/handler/static/handler.go b/pkg/handler/static/handler.go
 31index 779c78660309a955ece24d643d21877b610c2cad..6cc884ea1370a2a0268e04ed70a75e4f978c7c9f 100644
 32--- a/pkg/handler/static/handler.go
 33+++ b/pkg/handler/static/handler.go
 34@@ -1,6 +1,7 @@
 35 package static
 36 
 37 import (
 38+	"bytes"
 39 	"fmt"
 40 	"io"
 41 	"io/fs"
 42@@ -45,23 +46,32 @@ 	)
 43 
 44 	return func(w http.ResponseWriter, r *ext.Request) error {
 45 		ext.SetMIME(w, "text/css")
 46+		w.Header().Add("Cache-Control", "max-age=31536000")
 47+
 48+		// use buffer so this function can fail before writing to http.ResponseWriter
 49+		var buffer bytes.Buffer
 50 
 51 		var style *chroma.Style
 52 		style = darkStyle
 53-		w.Write([]byte("[data-bs-theme=\"dark\"] {\n"))
 54-		err := formatter.WriteCSS(&ws{w}, style)
 55+		buffer.Write([]byte("[data-bs-theme=\"dark\"] {\n"))
 56+		err := formatter.WriteCSS(&ws{&buffer}, style)
 57 		if err != nil {
 58 			return err
 59 		}
 60-		w.Write([]byte("}\n"))
 61+		buffer.Write([]byte("}\n"))
 62 
 63 		style = lightStyle
 64-		w.Write([]byte("[data-bs-theme=\"light\"] {\n"))
 65-		err = formatter.WriteCSS(&ws{w}, style)
 66+		buffer.Write([]byte("[data-bs-theme=\"light\"] {\n"))
 67+		err = formatter.WriteCSS(&ws{&buffer}, style)
 68 		if err != nil {
 69 			return err
 70 		}
 71-		w.Write([]byte("\n}"))
 72+		buffer.Write([]byte("}"))
 73+
 74+		_, err = io.Copy(w, &buffer)
 75+		if err != nil {
 76+			return err
 77+		}
 78 
 79 		return nil
 80 	}, nil
 81diff --git a/templates/base.qtpl b/templates/base.qtpl
 82index e43fb67fa5b7c74e9a0caa9057788cf46a4a614e..1dddb57bb0f0f60829259fc2eb60561c823a5b6f 100644
 83--- a/templates/base.qtpl
 84+++ b/templates/base.qtpl
 85@@ -60,8 +60,7 @@     <meta charset="utf-8">
 86     <link rel="icon" href="data:,">
 87     <title>{%= p.Title(ctx) %}</title> 
 88     <link rel="stylesheet" href="/static/main{%s Slug %}.css">
 89-    <link rel="stylesheet" href="/static/themes/dark">
 90-    <link rel="stylesheet" href="/static/themes/light">
 91+    <link rel="stylesheet" href="/static/theme{%s Slug %}.css">
 92     <html data-bs-theme="dark">
 93     <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
 94     <meta name="viewport" content="width=device-width, initial-scale=1" />
 95diff --git a/templates/base.qtpl.go b/templates/base.qtpl.go
 96index 783de2c10402a1a33125b1f872bc3db488ede7ab..3c4d8a94cc1649c5efd739976e21c045f8582db4 100644
 97--- a/templates/base.qtpl.go
 98+++ b/templates/base.qtpl.go
 99@@ -8,14 +8,16 @@ //line templates/base.qtpl:3
100 package templates
101 
102 //line templates/base.qtpl:3
103-import (
104-	"context"
105-	"strconv"
106-	"time" //line templates/base.qtpl:4
107+import "context"
108 
109-	//line templates/base.qtpl:5
110-	//line templates/base.qtpl:7
111+//line templates/base.qtpl:4
112+import "strconv"
113 
114+//line templates/base.qtpl:5
115+import "time"
116+
117+//line templates/base.qtpl:7
118+import (
119 	qtio422016 "io"
120 
121 	qt422016 "github.com/valyala/quicktemplate"
122@@ -110,60 +112,64 @@ //line templates/base.qtpl:62
123 	qw422016.E().S(Slug)
124 //line templates/base.qtpl:62
125 	qw422016.N().S(`.css">
126-    <link rel="stylesheet" href="/static/theme">
127+    <link rel="stylesheet" href="/static/theme`)
128+//line templates/base.qtpl:63
129+	qw422016.E().S(Slug)
130+//line templates/base.qtpl:63
131+	qw422016.N().S(`.css">
132     <html data-bs-theme="dark">
133     <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
134     <meta name="viewport" content="width=device-width, initial-scale=1" />
135   </head>
136   <body>
137     `)
138-//line templates/base.qtpl:70
139+//line templates/base.qtpl:69
140 	p.StreamNavbar(qw422016, ctx)
141-//line templates/base.qtpl:70
142+//line templates/base.qtpl:69
143 	qw422016.N().S(`
144     <div class="container">
145       `)
146-//line templates/base.qtpl:72
147+//line templates/base.qtpl:71
148 	p.StreamContent(qw422016, ctx)
149-//line templates/base.qtpl:72
150+//line templates/base.qtpl:71
151 	qw422016.N().S(`
152     </div>
153   </body>
154   `)
155-//line templates/base.qtpl:75
156+//line templates/base.qtpl:74
157 	p.StreamScript(qw422016, ctx)
158-//line templates/base.qtpl:75
159+//line templates/base.qtpl:74
160 	qw422016.N().S(`
161   <script>
162   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);
163   </script>
164 </html>
165 `)
166-//line templates/base.qtpl:80
167+//line templates/base.qtpl:79
168 }
169 
170-//line templates/base.qtpl:80
171+//line templates/base.qtpl:79
172 func WritePageTemplate(qq422016 qtio422016.Writer, p Page, ctx context.Context) {
173-//line templates/base.qtpl:80
174+//line templates/base.qtpl:79
175 	qw422016 := qt422016.AcquireWriter(qq422016)
176-//line templates/base.qtpl:80
177+//line templates/base.qtpl:79
178 	StreamPageTemplate(qw422016, p, ctx)
179-//line templates/base.qtpl:80
180+//line templates/base.qtpl:79
181 	qt422016.ReleaseWriter(qw422016)
182-//line templates/base.qtpl:80
183+//line templates/base.qtpl:79
184 }
185 
186-//line templates/base.qtpl:80
187+//line templates/base.qtpl:79
188 func PageTemplate(p Page, ctx context.Context) string {
189-//line templates/base.qtpl:80
190+//line templates/base.qtpl:79
191 	qb422016 := qt422016.AcquireByteBuffer()
192-//line templates/base.qtpl:80
193+//line templates/base.qtpl:79
194 	WritePageTemplate(qb422016, p, ctx)
195-//line templates/base.qtpl:80
196+//line templates/base.qtpl:79
197 	qs422016 := string(qb422016.B)
198-//line templates/base.qtpl:80
199+//line templates/base.qtpl:79
200 	qt422016.ReleaseByteBuffer(qb422016)
201-//line templates/base.qtpl:80
202+//line templates/base.qtpl:79
203 	return qs422016
204-//line templates/base.qtpl:80
205+//line templates/base.qtpl:79
206 }