From b0e09973aa66a17d24d42a8828a1424b1ca70541 Mon Sep 17 00:00:00 2001 From: Pineapple217 Date: Thu, 9 May 2024 22:59:59 +0200 Subject: [PATCH] added cache busting for static files --- cmd/server/main.go | 7 +- pkg/handler/manifest.go | 35 +++ pkg/server/middleware.go | 3 +- pkg/server/routes.go | 16 +- pkg/server/static/public/site.webmanifest | 6 - pkg/static/embed.go | 93 +++++++ .../static/public/apple-touch-icon.png | Bin pkg/{server => }/static/public/css/main.css | 0 pkg/{server => }/static/public/favicon.ico | Bin .../static/public/fonts/TerminusTTF.woff2 | Bin pkg/{server => }/static/public/icon-192.png | Bin pkg/{server => }/static/public/icon-512.png | Bin pkg/{server => }/static/public/icon.svg | 0 pkg/view/base.templ | 11 +- pkg/view/base_templ.go | 241 +++++++++++------- 15 files changed, 293 insertions(+), 119 deletions(-) create mode 100644 pkg/handler/manifest.go delete mode 100644 pkg/server/static/public/site.webmanifest create mode 100644 pkg/static/embed.go rename pkg/{server => }/static/public/apple-touch-icon.png (100%) rename pkg/{server => }/static/public/css/main.css (100%) rename pkg/{server => }/static/public/favicon.ico (100%) rename pkg/{server => }/static/public/fonts/TerminusTTF.woff2 (100%) rename pkg/{server => }/static/public/icon-192.png (100%) rename pkg/{server => }/static/public/icon-512.png (100%) rename pkg/{server => }/static/public/icon.svg (100%) diff --git a/cmd/server/main.go b/cmd/server/main.go index af958b3..90b481c 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -13,6 +13,7 @@ import ( "github.com/Pineapple217/mb/pkg/media" "github.com/Pineapple217/mb/pkg/scheduler" "github.com/Pineapple217/mb/pkg/server" + "github.com/Pineapple217/mb/pkg/static" ) // TODO: banner does not get printed first @@ -21,7 +22,7 @@ const banner = ` ·██ ▐███▪▐█ ▀█▪ ▐█ ▌▐▌▐█·▐█▀▀█▄ ██ ██▌▐█▌██▄▪▐█ -▀▀ █▪▀▀▀·▀▀▀▀ v0.7.1 +▀▀ █▪▀▀▀·▀▀▀▀ v0.7.2 Minimal blog with no JavaScript https://github.com/Pineapple217/mb -----------------------------------------------------------------------------` @@ -35,12 +36,14 @@ func main() { config.Load() + rr := static.HashPublicFS() + q := database.NewQueries("file:" + config.DataDir + "/database.db") h := handler.NewHandler(q) server := server.NewServer() server.RegisterRoutes(h) - server.ApplyMiddleware(q) + server.ApplyMiddleware(q, rr) server.Start() diff --git a/pkg/handler/manifest.go b/pkg/handler/manifest.go new file mode 100644 index 0000000..a561f13 --- /dev/null +++ b/pkg/handler/manifest.go @@ -0,0 +1,35 @@ +package handler + +import ( + "encoding/json" + "net/http" + + s "github.com/Pineapple217/mb/pkg/static" + "github.com/labstack/echo/v4" +) + +type Icon struct { + Src string `json:"src"` + Type string `json:"type"` + Sizes string `json:"sizes"` +} + +type IconSet struct { + Icons []Icon `json:"icons"` +} + +func (h *Handler) Manifest(c echo.Context) error { + // TODO: could cache the man + var manifest = IconSet{ + Icons: []Icon{ + {Src: s.StaticMap["/static/icon-192.png"], Type: "image/png", Sizes: "192x192"}, + {Src: s.StaticMap["/static/icon-512.png"], Type: "image/png", Sizes: "512x512"}, + }, + } + jsonData, err := json.Marshal(manifest) + if err != nil { + return err + } + c.Response().Header().Set("Content-Type", "application/manifest+json") + return c.String(http.StatusOK, string(jsonData)) +} diff --git a/pkg/server/middleware.go b/pkg/server/middleware.go index 7a018e6..a9efc36 100644 --- a/pkg/server/middleware.go +++ b/pkg/server/middleware.go @@ -11,8 +11,9 @@ import ( echoMw "github.com/labstack/echo/v4/middleware" ) -func (s *Server) ApplyMiddleware(q *database.Queries) { +func (s *Server) ApplyMiddleware(q *database.Queries, reRoutes map[string]string) { slog.Info("Applying middlewares") + s.e.Pre(echoMw.Rewrite(reRoutes)) s.e.Use(echoMw.RequestLoggerWithConfig(echoMw.RequestLoggerConfig{ LogStatus: true, LogURI: true, diff --git a/pkg/server/routes.go b/pkg/server/routes.go index f8bf0ea..0ec80c1 100644 --- a/pkg/server/routes.go +++ b/pkg/server/routes.go @@ -1,39 +1,33 @@ package server import ( - "embed" "log/slog" - "time" "github.com/Pineapple217/mb/pkg/config" "github.com/Pineapple217/mb/pkg/handler" "github.com/Pineapple217/mb/pkg/middleware" + "github.com/Pineapple217/mb/pkg/static" "github.com/labstack/echo/v4" ) -var ( - //go:embed static/public/* - publicFS embed.FS -) - func (server *Server) RegisterRoutes(hdlr *handler.Handler) { slog.Info("Registering routes") e := server.e s := e.Group("/static") - // TODO: post issue, StaticFS not getting cached - bootTime := time.Now().Add(-2 * time.Hour) + s.Use(func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { - c.Response().Header().Add("Last-Modified", bootTime.Local().UTC().Format("Mon, 2 Jan 2006 15:04:05 GMT")) + c.Response().Header().Add("Cache-Control", "public, max-age=31536000, immutable") return next(c) } }) - s.StaticFS("/", echo.MustSubFS(publicFS, "static/public")) + s.StaticFS("/", echo.MustSubFS(static.PublicFS, "public")) e.GET("/index.xml", hdlr.RSSFeed) e.GET("robot.txt", hdlr.RobotTxt) + e.GET("/site.webmanifest", hdlr.Manifest) //TODO better caching with http headers diff --git a/pkg/server/static/public/site.webmanifest b/pkg/server/static/public/site.webmanifest deleted file mode 100644 index 5ff8ac9..0000000 --- a/pkg/server/static/public/site.webmanifest +++ /dev/null @@ -1,6 +0,0 @@ -{ - "icons": [ - { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" }, - { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" } - ] -} \ No newline at end of file diff --git a/pkg/static/embed.go b/pkg/static/embed.go new file mode 100644 index 0000000..6995796 --- /dev/null +++ b/pkg/static/embed.go @@ -0,0 +1,93 @@ +package static + +import ( + "crypto/sha256" + "embed" + "encoding/hex" + "fmt" + "io" + "io/fs" + "log/slog" + "path/filepath" + "strings" +) + +var ( + //go:embed public/* + PublicFS embed.FS + excludeExts = []string{".woff2"} + StaticMap map[string]string +) + +func hashFile(file fs.File) (string, error) { + hash := sha256.New() + if _, err := io.Copy(hash, file); err != nil { + return "", err + } + sum := hash.Sum(nil) + + return hex.EncodeToString(sum)[:12], nil +} + +func hashFiles(f embed.FS) (map[string]string, error) { + filesDetails := map[string]string{} + + err := fs.WalkDir(f, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if !d.IsDir() { + ext := filepath.Ext(path) + for _, e := range excludeExts { + if ext == e { + return nil + } + } + + file, err := f.Open(path) + if err != nil { + return err + } + defer file.Close() + + hash, err := hashFile(file) + if err != nil { + return err + } + + fileName := strings.TrimSuffix(d.Name(), ext) + + newFilename := fmt.Sprintf("%s-%s%s", fileName, hash, ext) + basePath := strings.TrimSuffix(path, d.Name()) + basePath = strings.ReplaceAll(basePath, "public", "/static") + + p := strings.ReplaceAll(path, "public", "/static") + filesDetails[p] = basePath + newFilename + } + return nil + }) + + if err != nil { + return nil, err + } + + return filesDetails, nil +} + +func HashPublicFS() map[string]string { + slog.Info("Hashing static files") + files, err := hashFiles(PublicFS) + if err != nil { + panic(err) + } + + for k, v := range files { + slog.Info("file hashed", "old", k, "new", v) + } + StaticMap = files + swappedMap := make(map[string]string) + for k, v := range files { + swappedMap[v] = k + } + return swappedMap +} diff --git a/pkg/server/static/public/apple-touch-icon.png b/pkg/static/public/apple-touch-icon.png similarity index 100% rename from pkg/server/static/public/apple-touch-icon.png rename to pkg/static/public/apple-touch-icon.png diff --git a/pkg/server/static/public/css/main.css b/pkg/static/public/css/main.css similarity index 100% rename from pkg/server/static/public/css/main.css rename to pkg/static/public/css/main.css diff --git a/pkg/server/static/public/favicon.ico b/pkg/static/public/favicon.ico similarity index 100% rename from pkg/server/static/public/favicon.ico rename to pkg/static/public/favicon.ico diff --git a/pkg/server/static/public/fonts/TerminusTTF.woff2 b/pkg/static/public/fonts/TerminusTTF.woff2 similarity index 100% rename from pkg/server/static/public/fonts/TerminusTTF.woff2 rename to pkg/static/public/fonts/TerminusTTF.woff2 diff --git a/pkg/server/static/public/icon-192.png b/pkg/static/public/icon-192.png similarity index 100% rename from pkg/server/static/public/icon-192.png rename to pkg/static/public/icon-192.png diff --git a/pkg/server/static/public/icon-512.png b/pkg/static/public/icon-512.png similarity index 100% rename from pkg/server/static/public/icon-512.png rename to pkg/static/public/icon-512.png diff --git a/pkg/server/static/public/icon.svg b/pkg/static/public/icon.svg similarity index 100% rename from pkg/server/static/public/icon.svg rename to pkg/static/public/icon.svg diff --git a/pkg/view/base.templ b/pkg/view/base.templ index 15a2d82..d1c08ee 100644 --- a/pkg/view/base.templ +++ b/pkg/view/base.templ @@ -7,6 +7,7 @@ import ( "github.com/Pineapple217/mb/pkg/database" ct "github.com/Pineapple217/mb/pkg/context" "github.com/Pineapple217/mb/pkg/config" + s "github.com/Pineapple217/mb/pkg/static" ) templ boiler(desc string) { @@ -21,11 +22,11 @@ templ boiler(desc string) { if desc != "" { } - - - - - + + + + + mb diff --git a/pkg/view/base_templ.go b/pkg/view/base_templ.go index 41f134b..aa5b5d4 100644 --- a/pkg/view/base_templ.go +++ b/pkg/view/base_templ.go @@ -14,6 +14,7 @@ import ( "github.com/Pineapple217/mb/pkg/config" ct "github.com/Pineapple217/mb/pkg/context" "github.com/Pineapple217/mb/pkg/database" + s "github.com/Pineapple217/mb/pkg/static" "strconv" "strings" "time" @@ -44,7 +45,7 @@ func boiler(desc string) templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(desc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 22, Col: 43} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 23, Col: 43} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -55,7 +56,59 @@ func boiler(desc string) templ.Component { return templ_7745c5c3_Err } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("mb ") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("mb ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -82,21 +135,21 @@ func header() templ.Component { defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var3 := templ.GetChildren(ctx) - if templ_7745c5c3_Var3 == nil { - templ_7745c5c3_Var3 = templ.NopComponent + templ_7745c5c3_Var7 := templ.GetChildren(ctx) + if templ_7745c5c3_Var7 == nil { + templ_7745c5c3_Var7 = templ.NopComponent } ctx = templ.ClearChildren(ctx) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
")
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
-		var templ_7745c5c3_Var4 string
-		templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(config.HomepageLogo)
+		var templ_7745c5c3_Var8 string
+		templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(config.HomepageLogo)
 		if templ_7745c5c3_Err != nil {
-			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 42, Col: 25}
+			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 43, Col: 25}
 		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
+		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
@@ -104,8 +157,8 @@ func header() templ.Component {
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
-		var templ_7745c5c3_Var5 templ.SafeURL = templ.URL(config.HomepageLink)
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var5)))
+		var templ_7745c5c3_Var9 templ.SafeURL = templ.URL(config.HomepageLink)
+		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var9)))
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
@@ -113,12 +166,12 @@ func header() templ.Component {
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
-		var templ_7745c5c3_Var6 string
-		templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(config.HomepageLink)
+		var templ_7745c5c3_Var10 string
+		templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(config.HomepageLink)
 		if templ_7745c5c3_Err != nil {
-			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 47, Col: 68}
+			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 48, Col: 68}
 		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
+		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
@@ -126,12 +179,12 @@ func header() templ.Component {
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
-		var templ_7745c5c3_Var7 string
-		templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(config.HomepageRights)
+		var templ_7745c5c3_Var11 string
+		templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(config.HomepageRights)
 		if templ_7745c5c3_Err != nil {
-			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 48, Col: 32}
+			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 49, Col: 32}
 		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
+		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
@@ -139,12 +192,12 @@ func header() templ.Component {
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
-		var templ_7745c5c3_Var8 string
-		templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(time.Now().Year()))
+		var templ_7745c5c3_Var12 string
+		templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(time.Now().Year()))
 		if templ_7745c5c3_Err != nil {
-			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 49, Col: 37}
+			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 50, Col: 37}
 		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
+		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
@@ -152,12 +205,12 @@ func header() templ.Component {
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
-		var templ_7745c5c3_Var9 string
-		templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(ct.GetPostCountStr(ctx))
+		var templ_7745c5c3_Var13 string
+		templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(ct.GetPostCountStr(ctx))
 		if templ_7745c5c3_Err != nil {
-			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 51, Col: 40}
+			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 52, Col: 40}
 		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
+		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
@@ -165,12 +218,12 @@ func header() templ.Component {
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
-		var templ_7745c5c3_Var10 string
-		templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(config.HomepageMessage)
+		var templ_7745c5c3_Var14 string
+		templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(config.HomepageMessage)
 		if templ_7745c5c3_Err != nil {
-			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 53, Col: 28}
+			return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 54, Col: 28}
 		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
+		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
@@ -193,12 +246,12 @@ func Base(desc string, tags NullTags) templ.Component {
 			defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
 		}
 		ctx = templ.InitializeContext(ctx)
-		templ_7745c5c3_Var11 := templ.GetChildren(ctx)
-		if templ_7745c5c3_Var11 == nil {
-			templ_7745c5c3_Var11 = templ.NopComponent
+		templ_7745c5c3_Var15 := templ.GetChildren(ctx)
+		if templ_7745c5c3_Var15 == nil {
+			templ_7745c5c3_Var15 = templ.NopComponent
 		}
 		ctx = templ.ClearChildren(ctx)
-		templ_7745c5c3_Var12 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
+		templ_7745c5c3_Var16 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
 			templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
 			if !templ_7745c5c3_IsBuffer {
 				templ_7745c5c3_Buffer = templ.GetBuffer()
@@ -240,7 +293,7 @@ func Base(desc string, tags NullTags) templ.Component {
 			if templ_7745c5c3_Err != nil {
 				return templ_7745c5c3_Err
 			}
-			templ_7745c5c3_Err = templ_7745c5c3_Var11.Render(ctx, templ_7745c5c3_Buffer)
+			templ_7745c5c3_Err = templ_7745c5c3_Var15.Render(ctx, templ_7745c5c3_Buffer)
 			if templ_7745c5c3_Err != nil {
 				return templ_7745c5c3_Err
 			}
@@ -249,7 +302,7 @@ func Base(desc string, tags NullTags) templ.Component {
 			}
 			return templ_7745c5c3_Err
 		})
-		templ_7745c5c3_Err = boiler(desc).Render(templ.WithChildren(ctx, templ_7745c5c3_Var12), templ_7745c5c3_Buffer)
+		templ_7745c5c3_Err = boiler(desc).Render(templ.WithChildren(ctx, templ_7745c5c3_Var16), templ_7745c5c3_Buffer)
 		if templ_7745c5c3_Err != nil {
 			return templ_7745c5c3_Err
 		}
@@ -268,21 +321,21 @@ func search(tags []database.GetAllTagsRow) templ.Component {
 			defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
 		}
 		ctx = templ.InitializeContext(ctx)
-		templ_7745c5c3_Var13 := templ.GetChildren(ctx)
-		if templ_7745c5c3_Var13 == nil {
-			templ_7745c5c3_Var13 = templ.NopComponent
+		templ_7745c5c3_Var17 := templ.GetChildren(ctx)
+		if templ_7745c5c3_Var17 == nil {
+			templ_7745c5c3_Var17 = templ.NopComponent
 		}
 		ctx = templ.ClearChildren(ctx)
 		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Search ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var14 string - templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(ct.GetPostCountStr(ctx)) + var templ_7745c5c3_Var18 string + templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(ct.GetPostCountStr(ctx)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 80, Col: 60} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 81, Col: 60} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -290,12 +343,12 @@ func search(tags []database.GetAllTagsRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var15 string - templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(len(tags))) + var templ_7745c5c3_Var19 string + templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(len(tags))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 80, Col: 123} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 81, Col: 123} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -308,12 +361,12 @@ func search(tags []database.GetAllTagsRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var16 string - templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs("tag_" + tag.Tag.(string)) + var templ_7745c5c3_Var20 string + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs("tag_" + tag.Tag.(string)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 86, Col: 58} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 87, Col: 58} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -321,12 +374,12 @@ func search(tags []database.GetAllTagsRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var17 string - templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs("tag_" + tag.Tag.(string)) + var templ_7745c5c3_Var21 string + templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs("tag_" + tag.Tag.(string)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 86, Col: 93} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 87, Col: 93} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -334,12 +387,12 @@ func search(tags []database.GetAllTagsRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var18 string - templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs("tag_" + tag.Tag.(string)) + var templ_7745c5c3_Var22 string + templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs("tag_" + tag.Tag.(string)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 87, Col: 43} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 88, Col: 43} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -347,12 +400,12 @@ func search(tags []database.GetAllTagsRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var19 string - templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(tag.Tag.(string)) + var templ_7745c5c3_Var23 string + templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(tag.Tag.(string)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 87, Col: 64} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 88, Col: 64} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -360,12 +413,12 @@ func search(tags []database.GetAllTagsRow) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var20 string - templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.FormatInt(tag.TagCount, 10)) + var templ_7745c5c3_Var24 string + templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.FormatInt(tag.TagCount, 10)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 87, Col: 113} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 88, Col: 113} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -396,12 +449,12 @@ func EditPost(post database.Post) templ.Component { defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var21 := templ.GetChildren(ctx) - if templ_7745c5c3_Var21 == nil { - templ_7745c5c3_Var21 = templ.NopComponent + templ_7745c5c3_Var25 := templ.GetChildren(ctx) + if templ_7745c5c3_Var25 == nil { + templ_7745c5c3_Var25 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Var22 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { + templ_7745c5c3_Var26 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) if !templ_7745c5c3_IsBuffer { templ_7745c5c3_Buffer = templ.GetBuffer() @@ -411,8 +464,8 @@ func EditPost(post database.Post) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var23 templ.SafeURL = templ.URL("/post/" + strconv.FormatInt(post.CreatedAt, 10) + "/edit") - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var23))) + var templ_7745c5c3_Var27 templ.SafeURL = templ.URL("/post/" + strconv.FormatInt(post.CreatedAt, 10) + "/edit") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var27))) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -420,12 +473,12 @@ func EditPost(post database.Post) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var24 string - templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(post.Tags.String) + var templ_7745c5c3_Var28 string + templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(post.Tags.String) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 110, Col: 66} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 111, Col: 66} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -443,12 +496,12 @@ func EditPost(post database.Post) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var25 string - templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(getRows(post.Content)) + var templ_7745c5c3_Var29 string + templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(getRows(post.Content)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 120, Col: 56} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 121, Col: 56} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -456,12 +509,12 @@ func EditPost(post database.Post) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var26 string - templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(post.Content) + var templ_7745c5c3_Var30 string + templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(post.Content) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 120, Col: 86} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 121, Col: 86} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -469,12 +522,12 @@ func EditPost(post database.Post) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var27 string - templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.FormatInt(post.CreatedAt, 10)) + var templ_7745c5c3_Var31 string + templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.FormatInt(post.CreatedAt, 10)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 121, Col: 69} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pkg\view\base.templ`, Line: 122, Col: 69} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -487,7 +540,7 @@ func EditPost(post database.Post) templ.Component { } return templ_7745c5c3_Err }) - templ_7745c5c3_Err = Base("", NullTags{Valid: false}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var22), templ_7745c5c3_Buffer) + templ_7745c5c3_Err = Base("", NullTags{Valid: false}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var26), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -506,9 +559,9 @@ func createPost() templ.Component { defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var28 := templ.GetChildren(ctx) - if templ_7745c5c3_Var28 == nil { - templ_7745c5c3_Var28 = templ.NopComponent + templ_7745c5c3_Var32 := templ.GetChildren(ctx) + if templ_7745c5c3_Var32 == nil { + templ_7745c5c3_Var32 = templ.NopComponent } ctx = templ.ClearChildren(ctx) _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
New Post


")