Home

jolheiser.com @main - refs - log -
-
https://git.jolheiser.com/jolheiser.com.git
my website
tree log patch
templ as a go tool Signed-off-by: jolheiser <git@jolheiser.com>
Signature
-----BEGIN SSH SIGNATURE----- U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgBTEvCQk6VqUAdN2RuH6bj1dNkY oOpbPWj+jw4ua1B1cAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5 AAAAQA0Sgpvzi3WbvCl9RPYI1VcNk/w7/tvX0xqJ6eDpDKfBQy0xVMJYErC1q16z72W4KL 7T78kqLk8rqo5QVCpJnwg= -----END SSH SIGNATURE-----
jolheiser <git@jolheiser.com>
2 weeks ago
7 changed files, 330 additions(+), 78 deletions(-)
go.modgo.mod.srigo.summain.gosite.gosite.templsite_templ.go
M go.modgo.mod
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
diff --git a/go.mod b/go.mod
index a7f31231c72b0749d2d2566d06d140b30110a854..df3ecf543dfcce5e1149042edeea994cfded1d32 100644
--- a/go.mod
+++ b/go.mod
@@ -1,14 +1,32 @@
 module jolheiser.com
 
-go 1.21
+go 1.23.0
+
+toolchain go1.24.3
 
 require (
 	git.jojodev.com/jolheiser/simpleicons v0.0.3
+	github.com/a-h/templ v0.3.937
 	github.com/google/go-jsonnet v0.20.0
-	maragu.dev/gomponents v1.0.0
 )
 
 require (
+	github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect
+	github.com/andybalholm/brotli v1.1.0 // indirect
+	github.com/cenkalti/backoff/v4 v4.3.0 // indirect
+	github.com/cli/browser v1.3.0 // indirect
+	github.com/fatih/color v1.16.0 // indirect
+	github.com/fsnotify/fsnotify v1.7.0 // indirect
+	github.com/mattn/go-colorable v0.1.13 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/natefinch/atomic v1.0.1 // indirect
+	golang.org/x/mod v0.26.0 // indirect
+	golang.org/x/net v0.42.0 // indirect
+	golang.org/x/sync v0.16.0 // indirect
+	golang.org/x/sys v0.34.0 // indirect
+	golang.org/x/tools v0.35.0 // indirect
 	gopkg.in/yaml.v2 v2.2.7 // indirect
 	sigs.k8s.io/yaml v1.1.0 // indirect
 )
+
+tool github.com/a-h/templ/cmd/templ
M go.mod.srigo.mod.sri
1
2
3
4
5
6
7
8
9
diff --git a/go.mod.sri b/go.mod.sri
index 8989e01e68febd7e681bb5384a1356d7f48648e1..c82f91b4b706acf51122f0a71221546d6c6481f9 100644
--- a/go.mod.sri
+++ b/go.mod.sri
@@ -1 +1 @@
-sha256-e8dPVJnc7J9+9xGo+l1ccCzyF+iqOEGyRhRmdazmgCQ=
\ No newline at end of file
+sha256-krvlq8rfXyiF4SsnC46EJ9SvAYymCSgY0sFmzq4qbPE=
\ No newline at end of file
M go.sumgo.sum
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
diff --git a/go.sum b/go.sum
index 2e6b0d4c3f436e6fc469379d3473aaa4b64c711b..9ec91ec7233afb8ebb4060e0bf3c3a92c9a24d33 100644
--- a/go.sum
+++ b/go.sum
@@ -1,14 +1,55 @@
 git.jojodev.com/jolheiser/simpleicons v0.0.3 h1:R/UEcl6L6wAScHKu/oYyB0jY62inYes56aM91YlTfqE=
 git.jojodev.com/jolheiser/simpleicons v0.0.3/go.mod h1:NIhFsYI7rALmUX37teVRzf8BJAv1XtZC1OGeVjmB/No=
+github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ69NYAb5jbGNfHanvm1+iYlo=
+github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ=
+github.com/a-h/templ v0.3.937 h1:Ta+0Tf9YuZplUyKTUxReV36FCRKtK6FRMWpmXERHDnM=
+github.com/a-h/templ v0.3.937/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=
+github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
+github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
+github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
+github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
+github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=
+github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
+github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
+github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+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/google/go-jsonnet v0.20.0 h1:WG4TTSARuV7bSm4PMB4ohjxe33IHT5WVTrJSU33uT4g=
 github.com/google/go-jsonnet v0.20.0/go.mod h1:VbgWF9JX7ztlv770x/TolZNGGFfiHEVx9G6ca2eUmeA=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=
+github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
 github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
+golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
+golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
+golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
+golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
+golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
+golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
+golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
 gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-maragu.dev/gomponents v1.0.0 h1:eeLScjq4PqP1l+r5z/GC+xXZhLHXa6RWUWGW7gSfLh4=
-maragu.dev/gomponents v1.0.0/go.mod h1:oEDahza2gZoXDoDHhw8jBNgH+3UR5ni7Ur648HORydM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
 sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
M main.gomain.go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
diff --git a/main.go b/main.go
index 7df11bc4eb3f97e1006b84faf55a4c24b350570e..d2aaa07304b46e9ec28ea672877af60f101d1928 100644
--- a/main.go
+++ b/main.go
@@ -1,6 +1,8 @@
 package main
 
 import (
+	"context"
+	_ "embed"
 	"encoding/json"
 	"os"
 
@@ -8,6 +10,9 @@ 	"git.jojodev.com/jolheiser/simpleicons"
 	"github.com/google/go-jsonnet"
 )
 
+//go:embed qr.svg
+var qr string
+
 type Link struct {
 	Name     string `json:"name"`
 	URL      string `json:"url"`
@@ -18,6 +23,7 @@ func (l Link) Icon() simpleicons.Icon {
 	return simpleicons.Icons[l.IconName]
 }
 
+//go:generate go tool templ generate
 //go:generate go run .
 //go:generate tailwind-ctp-mocha -o ./dist/styles.css --minify
 func main() {
@@ -44,7 +50,7 @@ 		panic(err)
 	}
 	defer html.Close()
 
-	err = index(links.Links).Render(html)
+	err = index(links.Links).Render(context.Background(), html)
 	if err != nil {
 		panic(err)
 	}
D site.go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
diff --git a/site.go b/site.go
deleted file mode 100644
index 7e640c57a0f674a2106133deae85092e4827534c..0000000000000000000000000000000000000000
--- a/site.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package main
-
-import (
-	_ "embed"
-	"fmt"
-
-	g "maragu.dev/gomponents"
-	c "maragu.dev/gomponents/components"
-	h "maragu.dev/gomponents/html"
-)
-
-//go:embed qr.svg
-var qr string
-
-func index(links []Link) g.Node {
-	return c.HTML5(c.HTML5Props{
-		Title: "jolheiser",
-		Head: []g.Node{
-			// title, charset, and viewport are already set by HTML5
-			h.Link(h.Rel("shortcut icon"), h.Href("https://www.gravatar.com/avatar/7f4dd86f017ff289cf05a013e22357ef253d1ed6a52bdefca8f965af1080a965?s=16")),
-			h.Meta(h.Name("author"), h.Content("jolheiser")),
-			h.Link(h.Rel("stylesheet"), h.Href("styles.css")),
-		},
-		Body: []g.Node{
-			h.Class("bg-ctp-base"),
-			h.Header(h.Class("relative w-full pt-16 pb-10"),
-				h.Img(h.Class("mx-auto rounded-full"), h.Alt("avatar"), h.Src("https://www.gravatar.com/avatar/7f4dd86f017ff289cf05a013e22357ef253d1ed6a52bdefca8f965af1080a965?s=125")),
-				h.P(h.Class("mt-2 text-xl text-center text-ctp-lavender"),
-					g.Text("@jolheiser"),
-				),
-			),
-			h.Nav(h.Class("relative max-w-screen-sm mx-auto"),
-				g.Map(links, func(link Link) g.Node {
-					return h.A(h.Class("flex relative px-3 py-2 my-6 h-16 text-lg items-center justify-center text-ctp-text bg-ctp-surface0 cursor-pointer rounded border-solid border-2 border-overlay0 hover:bg-ctp-surface2 hover:border-ctp-lavender hover:text-ctp-blue transition"), h.Title(link.Name), h.Target("_blank"), h.Href(link.URL),
-						h.SVG(h.Class("absolute left-5 w-10 h-10"), h.Role("img"), ViewBox(0, 0, 24, 24), XMLNS(),
-							h.Title(link.Icon().Title),
-							Path(Fill("#"+link.Icon().Hex), D(link.Icon().Path)),
-						),
-						h.Span(g.Text(link.Name)),
-					)
-				}),
-			),
-			h.Footer(h.Class("relative w-full max-w-screen-sm mx-auto mt-10 pb-8 text-center"),
-				h.Div(h.Class("flex justify-center items-center"),
-					h.Div(h.Class("bg-ctp-surface2 p-3 rounded w-1/5"),
-						g.Raw(qr),
-					),
-				),
-			),
-		},
-	})
-}
-
-func ViewBox(minX, minY, width, height int) g.Node {
-	return g.Attr("viewBox", fmt.Sprintf("%d %d %d %d", minX, minY, width, height))
-}
-
-func XMLNS() g.Node {
-	return g.Attr("xmlns", "http://www.w3.org/2000/svg")
-}
-
-func Path(children ...g.Node) g.Node {
-	return g.El("path", children...)
-}
-
-func Fill(fill string) g.Node {
-	return g.Attr("fill", fill)
-}
-
-func D(d string) g.Node {
-	return g.Attr("d", d)
-}
I site.templ
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
diff --git a/site.templ b/site.templ
new file mode 100644
index 0000000000000000000000000000000000000000..756ef23dfbdb3c3ba0368b629b3b46ad0f965853
--- /dev/null
+++ b/site.templ
@@ -0,0 +1,44 @@
+package main
+
+templ head() {
+	<head>
+		<title>jolheiser</title>
+		<meta charset="utf-8"/>
+		<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+		<link rel="shortcut icon" href="https://www.gravatar.com/avatar/7f4dd86f017ff289cf05a013e22357ef253d1ed6a52bdefca8f965af1080a965?s=16"/>
+		<meta name="author" content="jolheiser"/>
+		<link rel="stylesheet" href="styles.css"/>
+	</head>
+}
+
+func fill(hex string) string {
+	return "#" + hex
+}
+
+templ body(links []Link) {
+	<body class="bg-ctp-base">
+		<header class="relative w-full pt-16 pb-10">
+			<img class="mx-auto rounded-full" alt="avatar" src="https://www.gravatar.com/avatar/7f4dd86f017ff289cf05a013e22357ef253d1ed6a52bdefca8f965af1080a965?s=125"/>
+			<p class="mt-2 text-xl text-center text-ctp-lavender">{ `@` }jolheiser</p>
+		</header>
+		<nav class="relative max-w-screen-sm mx-auto">
+			for _, link := range links {
+				<a class="flex relative px-3 py-2 my-6 h-16 text-lg items-center justify-center text-ctp-text bg-ctp-surface0 cursor-pointer rounded border-solid border-2 border-overlay0 hover:bg-ctp-surface2 hover:border-ctp-lavender hover:text-ctp-blue transition" href={ templ.SafeURL(link.URL) } rel="me noopener noreferrer" title={ link.Name } target="_blank"><svg class="absolute left-5 w-10 h-10" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>{ link.Icon().Title }</title><path fill={ fill(link.Icon().Hex) } d={ link.Icon().Path }></path></svg><span>{ link.Name }</span></a>
+			}
+		</nav>
+		<footer class="relative w-full max-w-screen-sm mx-auto mt-10 pb-8 text-center">
+			<div class="flex justify-center items-center">
+				<div class="bg-ctp-surface2 p-3 rounded w-1/5">
+					@templ.Raw(qr)
+				</div>
+			</div>
+		</footer>
+	</body>
+}
+
+templ index(links []Link) {
+	@head()
+	@body(links)
+}
+
+
I site_templ.go
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
diff --git a/site_templ.go b/site_templ.go
new file mode 100644
index 0000000000000000000000000000000000000000..f95d9698947457930d5b7d5855fa51b7f2c526f2
--- /dev/null
+++ b/site_templ.go
@@ -0,0 +1,215 @@
+// Code generated by templ - DO NOT EDIT.
+
+// templ: version: v0.3.937
+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"
+
+func head() 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 = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<head><title>jolheiser</title><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><link rel=\"shortcut icon\" href=\"https://www.gravatar.com/avatar/7f4dd86f017ff289cf05a013e22357ef253d1ed6a52bdefca8f965af1080a965?s=16\"><meta name=\"author\" content=\"jolheiser\"><link rel=\"stylesheet\" href=\"styles.css\"></head>")
+		if templ_7745c5c3_Err != nil {
+			return templ_7745c5c3_Err
+		}
+		return nil
+	})
+}
+
+func fill(hex string) string {
+	return "#" + hex
+}
+
+func body(links []Link) 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_Var2 := templ.GetChildren(ctx)
+		if templ_7745c5c3_Var2 == nil {
+			templ_7745c5c3_Var2 = templ.NopComponent
+		}
+		ctx = templ.ClearChildren(ctx)
+		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<body class=\"bg-ctp-base\"><header class=\"relative w-full pt-16 pb-10\"><img class=\"mx-auto rounded-full\" alt=\"avatar\" src=\"https://www.gravatar.com/avatar/7f4dd86f017ff289cf05a013e22357ef253d1ed6a52bdefca8f965af1080a965?s=125\"><p class=\"mt-2 text-xl text-center text-ctp-lavender\">")
+		if templ_7745c5c3_Err != nil {
+			return templ_7745c5c3_Err
+		}
+		var templ_7745c5c3_Var3 string
+		templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(`@`)
+		if templ_7745c5c3_Err != nil {
+			return templ.Error{Err: templ_7745c5c3_Err, FileName: `site.templ`, Line: 22, Col: 62}
+		}
+		_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
+		if templ_7745c5c3_Err != nil {
+			return templ_7745c5c3_Err
+		}
+		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "jolheiser</p></header><nav class=\"relative max-w-screen-sm mx-auto\">")
+		if templ_7745c5c3_Err != nil {
+			return templ_7745c5c3_Err
+		}
+		for _, link := range links {
+			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<a class=\"flex relative px-3 py-2 my-6 h-16 text-lg items-center justify-center text-ctp-text bg-ctp-surface0 cursor-pointer rounded border-solid border-2 border-overlay0 hover:bg-ctp-surface2 hover:border-ctp-lavender hover:text-ctp-blue transition\" href=\"")
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			var templ_7745c5c3_Var4 templ.SafeURL
+			templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(link.URL))
+			if templ_7745c5c3_Err != nil {
+				return templ.Error{Err: templ_7745c5c3_Err, FileName: `site.templ`, Line: 26, Col: 285}
+			}
+			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" rel=\"me noopener noreferrer\" title=\"")
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			var templ_7745c5c3_Var5 string
+			templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(link.Name)
+			if templ_7745c5c3_Err != nil {
+				return templ.Error{Err: templ_7745c5c3_Err, FileName: `site.templ`, Line: 26, Col: 334}
+			}
+			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\" target=\"_blank\"><svg class=\"absolute left-5 w-10 h-10\" role=\"img\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><title>")
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			var templ_7745c5c3_Var6 string
+			templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(link.Icon().Title)
+			if templ_7745c5c3_Err != nil {
+				return templ.Error{Err: templ_7745c5c3_Err, FileName: `site.templ`, Line: 26, Col: 484}
+			}
+			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</title><path fill=\"")
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			var templ_7745c5c3_Var7 string
+			templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(fill(link.Icon().Hex))
+			if templ_7745c5c3_Err != nil {
+				return templ.Error{Err: templ_7745c5c3_Err, FileName: `site.templ`, Line: 26, Col: 528}
+			}
+			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\" d=\"")
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			var templ_7745c5c3_Var8 string
+			templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(link.Icon().Path)
+			if templ_7745c5c3_Err != nil {
+				return templ.Error{Err: templ_7745c5c3_Err, FileName: `site.templ`, Line: 26, Col: 551}
+			}
+			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\"></path></svg><span>")
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			var templ_7745c5c3_Var9 string
+			templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(link.Name)
+			if templ_7745c5c3_Err != nil {
+				return templ.Error{Err: templ_7745c5c3_Err, FileName: `site.templ`, Line: 26, Col: 584}
+			}
+			_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+			templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</span></a>")
+			if templ_7745c5c3_Err != nil {
+				return templ_7745c5c3_Err
+			}
+		}
+		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</nav><footer class=\"relative w-full max-w-screen-sm mx-auto mt-10 pb-8 text-center\"><div class=\"flex justify-center items-center\"><div class=\"bg-ctp-surface2 p-3 rounded w-1/5\">")
+		if templ_7745c5c3_Err != nil {
+			return templ_7745c5c3_Err
+		}
+		templ_7745c5c3_Err = templ.Raw(qr).Render(ctx, templ_7745c5c3_Buffer)
+		if templ_7745c5c3_Err != nil {
+			return templ_7745c5c3_Err
+		}
+		templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "</div></div></footer></body>")
+		if templ_7745c5c3_Err != nil {
+			return templ_7745c5c3_Err
+		}
+		return nil
+	})
+}
+
+func index(links []Link) 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_Err = head().Render(ctx, templ_7745c5c3_Buffer)
+		if templ_7745c5c3_Err != nil {
+			return templ_7745c5c3_Err
+		}
+		templ_7745c5c3_Err = body(links).Render(ctx, templ_7745c5c3_Buffer)
+		if templ_7745c5c3_Err != nil {
+			return templ_7745c5c3_Err
+		}
+		return nil
+	})
+}
+
+var _ = templruntime.GeneratedTemplate