Home

blog @main - refs - log -
-
https://git.jolheiser.com/blog.git
My nonexistent blog
tree log patch
migrate to gomponents Signed-off-by: jolheiser <git@jolheiser.com>
Signature
-----BEGIN SSH SIGNATURE----- U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgBTEvCQk6VqUAdN2RuH6bj1dNkY oOpbPWj+jw4ua1B1cAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5 AAAAQEMNzdxE2Um1sYP0UueIGmA49hwPMbzWj3Y2o2nHK4I2FoNo+RaBMxxriOy8iIwDa3 VqjuevNetUhW3ueYTxUw8= -----END SSH SIGNATURE-----
jolheiser <git@jolheiser.com>
5 days ago
10 changed files, 112 additions(+), 554 deletions(-)
M flake.lock -> flake.lock
diff --git a/flake.lock b/flake.lock
index f5bcb522d6f69dcc5e62033951b6297b31a4d3aa..e44a27858743e763f38bf246902f21a8561b6d93 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,81 +1,5 @@
 {
   "nodes": {
-    "flake-utils": {
-      "inputs": {
-        "systems": "systems"
-      },
-      "locked": {
-        "lastModified": 1694529238,
-        "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "type": "github"
-      }
-    },
-    "flake-utils_2": {
-      "locked": {
-        "lastModified": 1667395993,
-        "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
-        "type": "github"
-      },
-      "original": {
-        "owner": "numtide",
-        "repo": "flake-utils",
-        "type": "github"
-      }
-    },
-    "gitignore": {
-      "inputs": {
-        "nixpkgs": [
-          "templ",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1709087332,
-        "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
-        "owner": "hercules-ci",
-        "repo": "gitignore.nix",
-        "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
-        "type": "github"
-      },
-      "original": {
-        "owner": "hercules-ci",
-        "repo": "gitignore.nix",
-        "type": "github"
-      }
-    },
-    "gomod2nix": {
-      "inputs": {
-        "flake-utils": "flake-utils",
-        "nixpkgs": [
-          "templ",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1722589758,
-        "narHash": "sha256-sbbA8b6Q2vB/t/r1znHawoXLysCyD4L/6n6/RykiSnA=",
-        "owner": "nix-community",
-        "repo": "gomod2nix",
-        "rev": "4e08ca09253ef996bd4c03afa383b23e35fe28a1",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-community",
-        "repo": "gomod2nix",
-        "type": "github"
-      }
-    },
     "nixpkgs": {
       "locked": {
         "lastModified": 1728679842,
@@ -93,68 +17,7 @@       }
     },
     "root": {
       "inputs": {
-        "nixpkgs": "nixpkgs",
-        "templ": "templ"
-      }
-    },
-    "systems": {
-      "locked": {
-        "lastModified": 1681028828,
-        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
-        "owner": "nix-systems",
-        "repo": "default",
-        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nix-systems",
-        "repo": "default",
-        "type": "github"
-      }
-    },
-    "templ": {
-      "inputs": {
-        "gitignore": "gitignore",
-        "gomod2nix": "gomod2nix",
-        "nixpkgs": [
-          "nixpkgs"
-        ],
-        "xc": "xc"
-      },
-      "locked": {
-        "lastModified": 1728028863,
-        "narHash": "sha256-NEkcOnjMN+fI9/Lejy6As3/Cd0rxqU4c4Dwt7OYiiLM=",
-        "owner": "a-h",
-        "repo": "templ",
-        "rev": "318249d145b66fe1d66e34abf2321c86e1dfbc52",
-        "type": "github"
-      },
-      "original": {
-        "owner": "a-h",
-        "repo": "templ",
-        "type": "github"
-      }
-    },
-    "xc": {
-      "inputs": {
-        "flake-utils": "flake-utils_2",
-        "nixpkgs": [
-          "templ",
-          "nixpkgs"
-        ]
-      },
-      "locked": {
-        "lastModified": 1724404748,
-        "narHash": "sha256-p6rXzNiDm2uBvO1MLzC5pJp/0zRNzj/snBzZI0ce62s=",
-        "owner": "joerdav",
-        "repo": "xc",
-        "rev": "960ff9f109d47a19122cfb015721a76e3a0f23a2",
-        "type": "github"
-      },
-      "original": {
-        "owner": "joerdav",
-        "repo": "xc",
-        "type": "github"
+        "nixpkgs": "nixpkgs"
       }
     }
   },
M flake.nix -> flake.nix
diff --git a/flake.nix b/flake.nix
index a1035961990ef9c3456531756fbb44e2041919d0..5f2080a8a7ab812405cba8a6fb7e616980ae62ef 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,22 +1,14 @@
 {
-  inputs = {
-    nixpkgs.url = "github:nixos/nixpkgs";
-    templ = {
-      url = "github:a-h/templ";
-      inputs.nixpkgs.follows = "nixpkgs";
-    };
-  };
+  inputs.nixpkgs.url = "github:nixos/nixpkgs";
 
   outputs =
     {
       self,
       nixpkgs,
-      templ,
-    }@inputs:
+    }:
     let
       system = "x86_64-linux";
       pkgs = nixpkgs.legacyPackages.${system};
-      templ = inputs.templ.packages.${system}.templ;
     in
     {
       packages.${system}.default = pkgs.buildGoModule {
@@ -24,7 +16,6 @@         pname = "blog.jolheiser.com";
         version = "blog";
         src = ./.;
         vendorHash = nixpkgs.lib.fileContents ./go.mod.sri;
-        nativeBuildInputs = [ templ ];
         excludedPackages = ".";
         postBuild = ''
           export BLOG_REF=${self.rev or "main"}
@@ -35,7 +26,6 @@       };
       devShells.default = pkgs.mkShell {
         nativeBuildInputs = with pkgs; [
           go
-          templ
           vscode-langservers-extracted
         ];
       };
M go.mod -> go.mod
diff --git a/go.mod b/go.mod
index e83daac31f4290202ee032f1f498df6067f1bfaf..6612b487ce9569eb6f6631fbcd942dd368822da8 100644
--- a/go.mod
+++ b/go.mod
@@ -4,13 +4,13 @@ go 1.21.6
 
 require (
 	github.com/BurntSushi/toml v1.3.2
-	github.com/a-h/templ v0.2.778
 	github.com/alecthomas/chroma/v2 v2.12.0
 	github.com/gorilla/feeds v1.1.2
 	github.com/yuin/goldmark v1.7.0
 	github.com/yuin/goldmark-emoji v1.0.2
 	github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
 	github.com/yuin/goldmark-meta v1.1.0
+	maragu.dev/gomponents v1.0.0
 )
 
 require (
M go.mod.sri -> go.mod.sri
diff --git a/go.mod.sri b/go.mod.sri
index 7787f01765df1420a0e1db54ada9b7c5842e76af..2e45981dcfb9dfc156c9d140e67423b2a36d9cdb 100644
--- a/go.mod.sri
+++ b/go.mod.sri
@@ -1 +1 @@
-sha256-AdXfH+hHYm0KXW9eXquZnWt49EimmMjpbUYOMEvamX8=
\ No newline at end of file
+sha256-oWVGWTuqOTwGw9Kkx48PRzpmpgDkkAEJC6js0S1Aeok=
\ No newline at end of file
M go.sum -> go.sum
diff --git a/go.sum b/go.sum
index 5623fc73ffd61df27ee192120e5fa9d9d3d8ec3e..3689afea929185f9a2999bd96e0bb387efed908e 100644
--- a/go.sum
+++ b/go.sum
@@ -1,7 +1,5 @@
 github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
 github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
-github.com/a-h/templ v0.2.778 h1:VzhOuvWECrwOec4790lcLlZpP4Iptt5Q4K9aFxQmtaM=
-github.com/a-h/templ v0.2.778/go.mod h1:lq48JXoUvuQrU0VThrK31yFwdRjTCnIE5bcPCM9IP1w=
 github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink=
 github.com/alecthomas/assert/v2 v2.2.1/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
 github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
@@ -16,8 +14,6 @@ github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
 github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
 github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
 github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/gorilla/feeds v1.1.2 h1:pxzZ5PD3RJdhFH2FsJJ4x6PqMqbgFk1+Vez4XWBW8Iw=
 github.com/gorilla/feeds v1.1.2/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
 github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
@@ -47,3 +43,5 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+maragu.dev/gomponents v1.0.0 h1:eeLScjq4PqP1l+r5z/GC+xXZhLHXa6RWUWGW7gSfLh4=
+maragu.dev/gomponents v1.0.0/go.mod h1:oEDahza2gZoXDoDHhw8jBNgH+3UR5ni7Ur648HORydM=
I html/html.go
diff --git a/html/html.go b/html/html.go
new file mode 100644
index 0000000000000000000000000000000000000000..647975c240e21fe427b758ecd8da3bd400f26541
--- /dev/null
+++ b/html/html.go
@@ -0,0 +1,91 @@
+package html
+
+import (
+	"fmt"
+	"os"
+
+	"blog.jolheiser.com/article"
+	. "maragu.dev/gomponents"
+	. "maragu.dev/gomponents/components"
+	. "maragu.dev/gomponents/html"
+)
+
+var ref = "main"
+
+func init() {
+	if r, ok := os.LookupEnv("BLOG_REF"); ok {
+		ref = r
+	}
+}
+
+func base(title, description string, children ...Node) Node {
+	return HTML5(HTML5Props{
+		Title:       title,
+		Description: description,
+		Head: []Node{
+			Meta(Property("og:title"), Content(title)),
+			Meta(Property("og:description"), Content(description)),
+			Link(Rel("alternate"), Type("application/atom+xml"), Href("feed.atom")),
+			Link(Rel("stylesheet"), Href("sakura.css")),
+			Link(Rel("stylesheet"), Href("chroma.css")),
+			Link(Rel("stylesheet"), Href("jolheiser.css")),
+		},
+		Body: children,
+	})
+}
+
+func published(articles []article.Article) int {
+	var num int
+	for _, a := range articles {
+		if !a.Draft {
+			num++
+		}
+	}
+	return num
+}
+
+func IndexHTML(articles article.Articles) Node {
+	categories := make([]Node, 0, len(articles))
+	for category, articles := range articles {
+		if published(articles) > 0 {
+			categories = append(categories, Group([]Node{
+				H3(Text(category)),
+				Ul(Map(articles, func(article article.Article) Node {
+					if article.Draft {
+						return nil
+					}
+					return Li(
+						A(Href(article.Slug()), Text(article.Title)),
+					)
+				})),
+			}))
+		}
+	}
+	return base("jolheiser's blog", "Hahaha yes.....YES!", []Node{
+		Header(
+			H1(Text("jolheiser")),
+			P(Text("Just a guy living in the middle of nowhere who likes to hack on open-source.")),
+		),
+		Main(Group(categories)),
+	}...)
+}
+
+func ArticleHTML(article article.Article) Node {
+	return base(article.Title, article.Summary, []Node{
+		Header(
+			H1(A(Href("/"), Small(Text("jolheiser")))),
+			Hr(),
+			H2(Text(article.Title)),
+			Div(Style("display: flex;"),
+				P(Style("flex: auto;"), Em(Text(article.Category))),
+				P(Style("flex: auto;"), Em(Title(article.Date.Format("Monday, January 2, 2006")), Text(article.Date.Format("Mon, 02 Jan 2006")))),
+			),
+		),
+		Main(Raw(article.Content)),
+		Footer(A(Href(fmt.Sprintf("https://git.jolheiser.com/blog/tree/%s/%s", ref, article.Path)), Text("source"))),
+	}...)
+}
+
+func Property(property string) Node {
+	return Attr("property", property)
+}
M main.go -> main.go
diff --git a/main.go b/main.go
index 923f70e2c86e9380566371d2768f93b28179dd9d..ccd2dcfbeeeb317462b5f0eaabf01be89c568092 100644
--- a/main.go
+++ b/main.go
@@ -1,9 +1,7 @@
-//go:generate templ generate
 //go:generate go run .
 package main
 
 import (
-	"context"
 	"embed"
 	"flag"
 	"fmt"
@@ -14,6 +12,8 @@ 	"os"
 	"path/filepath"
 	"time"
 
+	"blog.jolheiser.com/article"
+	"blog.jolheiser.com/html"
 	"github.com/alecthomas/chroma/v2/styles"
 	"github.com/gorilla/feeds"
 )
@@ -23,15 +23,8 @@ 	//go:embed articles/*
 	articleFS embed.FS
 	//go:embed static/*
 	staticFS embed.FS
-	ref      string = "main"
 )
 
-func init() {
-	if r, ok := os.LookupEnv("BLOG_REF"); ok {
-		ref = r
-	}
-}
-
 func maine() error {
 	fs := flag.NewFlagSet("blog", flag.ExitOnError)
 	outFlag := fs.String("out", "out", "Output directory")
@@ -47,8 +40,8 @@ 	if err != nil {
 		return err
 	}
 
-	categories := make(Articles)
-	articles := make([]Article, 0, len(files))
+	categories := make(article.Articles)
+	articles := make([]article.Article, 0, len(files))
 	for _, file := range files {
 		if filepath.Ext(file.Name()) != ".md" {
 			continue
@@ -58,11 +51,11 @@ 		content, err := iofs.ReadFile(articleFS, path)
 		if err != nil {
 			return err
 		}
-		article, err := Parse(string(content))
+		article, err := article.Parse(string(content))
 		if err != nil {
 			return err
 		}
-		article.path = path
+		article.Path = path
 		categories[article.Category] = append(categories[article.Category], article)
 		articles = append(articles, article)
 		if err := writeArticle(*outFlag, article); err != nil {
@@ -88,7 +81,7 @@ 		return err
 	}
 	defer fi.Close()
 
-	if err := IndexTemplate(categories).Render(context.Background(), fi); err != nil {
+	if err := html.IndexHTML(categories).Render(fi); err != nil {
 		return err
 	}
 
@@ -101,7 +94,7 @@
 	return nil
 }
 
-func writeArticle(out string, article Article) error {
+func writeArticle(out string, article article.Article) error {
 	dest := filepath.Join(out, article.Slug(), "index.html")
 	if err := os.MkdirAll(filepath.Dir(dest), os.ModePerm); err != nil {
 		return err
@@ -113,10 +106,10 @@ 		return err
 	}
 	defer fi.Close()
 
-	return ArticleTemplate(article).Render(context.Background(), fi)
+	return html.ArticleHTML(article).Render(fi)
 }
 
-func writeRSS(out string, articles []Article) error {
+func writeRSS(out string, articles []article.Article) error {
 	fi, err := os.Create(filepath.Join(out, "feed.atom"))
 	if err != nil {
 		return err
@@ -133,7 +126,6 @@ 			Email: "john@jolheiser.com",
 		},
 		Updated: time.Now(),
 		Created: time.Date(2024, time.February, 25, 0, 0, 0, 0, time.Local),
-		// Image:       &feeds.Image{},
 	}
 	for _, article := range articles {
 		if article.Draft {
@@ -146,7 +138,6 @@ 			Link:        &feeds.Link{Href: url},
 			Description: article.Summary,
 			Id:          url,
 			Created:     article.Date,
-			// Content:     article.Content,
 		})
 	}
 
@@ -160,11 +151,11 @@ 		return err
 	}
 	defer fi.Close()
 
-	if err := CSS.WriteCSS(fi, styles.Get("catppuccin-latte")); err != nil {
+	if err := article.CSS.WriteCSS(fi, styles.Get("catppuccin-latte")); err != nil {
 		return err
 	}
 	fi.WriteString("@media (prefers-color-scheme: dark) {")
-	if err := CSS.WriteCSS(fi, styles.Get("catppuccin-mocha")); err != nil {
+	if err := article.CSS.WriteCSS(fi, styles.Get("catppuccin-mocha")); err != nil {
 		return err
 	}
 	fi.WriteString("}")
M templates.go -> article/article.go
diff --git a/templates.go b/article/article.go
rename from templates.go
rename to article/article.go
index eac3264e98393a7f3d716c7531062157f9bbb7c7..c64176615e798ea219fac2d7139316204ba2ef8b 100644
--- a/templates.go
+++ b/article/article.go
@@ -1,4 +1,4 @@
-package main
+package article
 
 import (
 	"bytes"
@@ -35,7 +35,7 @@ 	Summary  string
 	Date     time.Time
 	Category string
 	Draft    bool
-	path     string
+	Path     string
 }
 
 type Author struct {
D templates.templ
diff --git a/templates.templ b/templates.templ
deleted file mode 100644
index 912542a625ac0847b82b52d54ad021328ea91716..0000000000000000000000000000000000000000
--- a/templates.templ
+++ /dev/null
@@ -1,64 +0,0 @@
-package main
-
-import "fmt"
-
-templ baseTemplate(title, description string) {
-	<!DOCTYPE html>
-	<html>
-		<head>
-			<meta charset="UTF-8"/>
-			<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-			<title>{ title }</title>
-			<meta property="og:title" content={ title }/>
-			<meta property="og:description" content={ description }/>
-			<link rel="alternate" type="application/atom+xml" href="/feed.atom"/>
-			<link rel="stylesheet" href="/sakura.css"/>
-			<link rel="stylesheet" href="/chroma.css"/>
-			<link rel="stylesheet" href="/jolheiser.css"/>
-		</head>
-		<body>
-			{ children... }
-		</body>
-	</html>
-}
-
-templ IndexTemplate(articles Articles) {
-	@baseTemplate("jolheiser's blog", "Hahaha yes.....YES!") {
-		<header>
-			<h1>jolheiser</h1>
-			<p>Just a guy living in the middle of nowhere who likes to hack on open-source.</p>
-		</header>
-		<main>
-			for category, articles := range articles {
-				if Published(articles) > 0 {
-					<h3>{ category }</h3>
-					<ul>
-						for _, article := range articles {
-							if !article.Draft {
-								<li><a href={ templ.SafeURL(article.Slug()) }>{ article.Title }</a></li>
-							}
-						}
-					</ul>
-				}
-			}
-		</main>
-	}
-}
-
-templ ArticleTemplate(article Article) {
-	@baseTemplate(article.Title, article.Summary) {
-		<header>
-			<h1><a href="/"><small>jolheiser</small></a></h1>
-			<hr/>
-			<h2>{ article.Title }</h2>
-			<div style="display:flex;">
-				<p style="flex:auto;"><em>{ article.Category }</em></p>
-				<p style="flex:auto;"><em title={ article.Date.Format("Monday, January 2, 2006") }>{ article.Date.Format("Mon, 02 Jan 2006") }</em></p>
-			</div>
-		</header>
-		<main>
-			@templ.Raw(article.Content)
-		</main>
-		<footer><a href={ templ.SafeURL(fmt.Sprintf("https://git.jolheiser.com/blog/tree/%s/%s", ref, article.path)) }>source</a></footer>
-	}
-}
D templates_templ.go
diff --git a/templates_templ.go b/templates_templ.go
deleted file mode 100644
index 265e3907885666585761805e55ee48fd6d4297af..0000000000000000000000000000000000000000
--- a/templates_templ.go
+++ /dev/null
@@ -1,311 +0,0 @@
-// Code generated by templ - DO NOT EDIT.
-
-// templ: version: v0.2.786
-package main
-
-//lint:file-ignore SA4006 This context is only used if a nested component is present.
-
-import "github.com/a-h/templ"
-import templruntime "github.com/a-h/templ/runtime"
-
-import "fmt"
-
-func baseTemplate(title, description string) templ.Component {
-	return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
-		templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
-		if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
-			return templ_7745c5c3_CtxErr
-		}
-		templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
-		if !templ_7745c5c3_IsBuffer {
-			defer func() {
-				templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
-				if templ_7745c5c3_Err == nil {
-					templ_7745c5c3_Err = templ_7745c5c3_BufErr
-				}
-			}()
-		}
-		ctx = templ.InitializeContext(ctx)
-		templ_7745c5c3_Var1 := templ.GetChildren(ctx)
-		if templ_7745c5c3_Var1 == nil {
-			templ_7745c5c3_Var1 = templ.NopComponent
-		}
-		ctx = templ.ClearChildren(ctx)
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>")
-		if templ_7745c5c3_Err != nil {
-			return templ_7745c5c3_Err
-		}
-		var templ_7745c5c3_Var2 string
-		templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title)
-		if templ_7745c5c3_Err != nil {
-			return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates.templ`, Line: 11, Col: 17}
-		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
-		if templ_7745c5c3_Err != nil {
-			return templ_7745c5c3_Err
-		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</title><meta property=\"og:title\" content=\"")
-		if templ_7745c5c3_Err != nil {
-			return templ_7745c5c3_Err
-		}
-		var templ_7745c5c3_Var3 string
-		templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(title)
-		if templ_7745c5c3_Err != nil {
-			return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates.templ`, Line: 12, Col: 44}
-		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
-		if templ_7745c5c3_Err != nil {
-			return templ_7745c5c3_Err
-		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><meta property=\"og:description\" content=\"")
-		if templ_7745c5c3_Err != nil {
-			return templ_7745c5c3_Err
-		}
-		var templ_7745c5c3_Var4 string
-		templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(description)
-		if templ_7745c5c3_Err != nil {
-			return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates.templ`, Line: 13, Col: 56}
-		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
-		if templ_7745c5c3_Err != nil {
-			return templ_7745c5c3_Err
-		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><link rel=\"alternate\" type=\"application/atom+xml\" href=\"/feed.atom\"><link rel=\"stylesheet\" href=\"/sakura.css\"><link rel=\"stylesheet\" href=\"/chroma.css\"><link rel=\"stylesheet\" href=\"/jolheiser.css\"></head><body>")
-		if templ_7745c5c3_Err != nil {
-			return templ_7745c5c3_Err
-		}
-		templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
-		if templ_7745c5c3_Err != nil {
-			return templ_7745c5c3_Err
-		}
-		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</body></html>")
-		if templ_7745c5c3_Err != nil {
-			return templ_7745c5c3_Err
-		}
-		return templ_7745c5c3_Err
-	})
-}
-
-func IndexTemplate(articles Articles) templ.Component {
-	return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
-		templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
-		if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
-			return templ_7745c5c3_CtxErr
-		}
-		templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
-		if !templ_7745c5c3_IsBuffer {
-			defer func() {
-				templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
-				if templ_7745c5c3_Err == nil {
-					templ_7745c5c3_Err = templ_7745c5c3_BufErr
-				}
-			}()
-		}
-		ctx = templ.InitializeContext(ctx)
-		templ_7745c5c3_Var5 := templ.GetChildren(ctx)
-		if templ_7745c5c3_Var5 == nil {
-			templ_7745c5c3_Var5 = templ.NopComponent
-		}
-		ctx = templ.ClearChildren(ctx)
-		templ_7745c5c3_Var6 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
-			templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
-			templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
-			if !templ_7745c5c3_IsBuffer {
-				defer func() {
-					templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
-					if templ_7745c5c3_Err == nil {
-						templ_7745c5c3_Err = templ_7745c5c3_BufErr
-					}
-				}()
-			}
-			ctx = templ.InitializeContext(ctx)
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<header><h1>jolheiser</h1><p>Just a guy living in the middle of nowhere who likes to hack on open-source.</p></header><main>")
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			for category, articles := range articles {
-				if Published(articles) > 0 {
-					_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<h3>")
-					if templ_7745c5c3_Err != nil {
-						return templ_7745c5c3_Err
-					}
-					var templ_7745c5c3_Var7 string
-					templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(category)
-					if templ_7745c5c3_Err != nil {
-						return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates.templ`, Line: 34, Col: 19}
-					}
-					_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
-					if templ_7745c5c3_Err != nil {
-						return templ_7745c5c3_Err
-					}
-					_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h3><ul>")
-					if templ_7745c5c3_Err != nil {
-						return templ_7745c5c3_Err
-					}
-					for _, article := range articles {
-						if !article.Draft {
-							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<li><a href=\"")
-							if templ_7745c5c3_Err != nil {
-								return templ_7745c5c3_Err
-							}
-							var templ_7745c5c3_Var8 templ.SafeURL = templ.SafeURL(article.Slug())
-							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var8)))
-							if templ_7745c5c3_Err != nil {
-								return templ_7745c5c3_Err
-							}
-							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
-							if templ_7745c5c3_Err != nil {
-								return templ_7745c5c3_Err
-							}
-							var templ_7745c5c3_Var9 string
-							templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(article.Title)
-							if templ_7745c5c3_Err != nil {
-								return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates.templ`, Line: 38, Col: 69}
-							}
-							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
-							if templ_7745c5c3_Err != nil {
-								return templ_7745c5c3_Err
-							}
-							_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></li>")
-							if templ_7745c5c3_Err != nil {
-								return templ_7745c5c3_Err
-							}
-						}
-					}
-					_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</ul>")
-					if templ_7745c5c3_Err != nil {
-						return templ_7745c5c3_Err
-					}
-				}
-			}
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</main>")
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			return templ_7745c5c3_Err
-		})
-		templ_7745c5c3_Err = baseTemplate("jolheiser's blog", "Hahaha yes.....YES!").Render(templ.WithChildren(ctx, templ_7745c5c3_Var6), templ_7745c5c3_Buffer)
-		if templ_7745c5c3_Err != nil {
-			return templ_7745c5c3_Err
-		}
-		return templ_7745c5c3_Err
-	})
-}
-
-func ArticleTemplate(article Article) templ.Component {
-	return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
-		templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
-		if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
-			return templ_7745c5c3_CtxErr
-		}
-		templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
-		if !templ_7745c5c3_IsBuffer {
-			defer func() {
-				templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
-				if templ_7745c5c3_Err == nil {
-					templ_7745c5c3_Err = templ_7745c5c3_BufErr
-				}
-			}()
-		}
-		ctx = templ.InitializeContext(ctx)
-		templ_7745c5c3_Var10 := templ.GetChildren(ctx)
-		if templ_7745c5c3_Var10 == nil {
-			templ_7745c5c3_Var10 = templ.NopComponent
-		}
-		ctx = templ.ClearChildren(ctx)
-		templ_7745c5c3_Var11 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
-			templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
-			templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
-			if !templ_7745c5c3_IsBuffer {
-				defer func() {
-					templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
-					if templ_7745c5c3_Err == nil {
-						templ_7745c5c3_Err = templ_7745c5c3_BufErr
-					}
-				}()
-			}
-			ctx = templ.InitializeContext(ctx)
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<header><h1><a href=\"/\"><small>jolheiser</small></a></h1><hr><h2>")
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			var templ_7745c5c3_Var12 string
-			templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(article.Title)
-			if templ_7745c5c3_Err != nil {
-				return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates.templ`, Line: 53, Col: 22}
-			}
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h2><div style=\"display:flex;\"><p style=\"flex:auto;\"><em>")
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			var templ_7745c5c3_Var13 string
-			templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(article.Category)
-			if templ_7745c5c3_Err != nil {
-				return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates.templ`, Line: 55, Col: 48}
-			}
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</em></p><p style=\"flex:auto;\"><em title=\"")
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			var templ_7745c5c3_Var14 string
-			templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(article.Date.Format("Monday, January 2, 2006"))
-			if templ_7745c5c3_Err != nil {
-				return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates.templ`, Line: 56, Col: 84}
-			}
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			var templ_7745c5c3_Var15 string
-			templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(article.Date.Format("Mon, 02 Jan 2006"))
-			if templ_7745c5c3_Err != nil {
-				return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates.templ`, Line: 56, Col: 128}
-			}
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</em></p></div></header><main>")
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			templ_7745c5c3_Err = templ.Raw(article.Content).Render(ctx, templ_7745c5c3_Buffer)
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</main><footer><a href=\"")
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			var templ_7745c5c3_Var16 templ.SafeURL = templ.SafeURL(fmt.Sprintf("https://git.jolheiser.com/blog/tree/%s/%s", ref, article.path))
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var16)))
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">source</a></footer>")
-			if templ_7745c5c3_Err != nil {
-				return templ_7745c5c3_Err
-			}
-			return templ_7745c5c3_Err
-		})
-		templ_7745c5c3_Err = baseTemplate(article.Title, article.Summary).Render(templ.WithChildren(ctx, templ_7745c5c3_Var11), templ_7745c5c3_Buffer)
-		if templ_7745c5c3_Err != nil {
-			return templ_7745c5c3_Err
-		}
-		return templ_7745c5c3_Err
-	})
-}
-
-var _ = templruntime.GeneratedTemplate