Compare commits
10 Commits
3eeb4c8b48
...
08f0f02ff6
Author | SHA1 | Date | |
---|---|---|---|
08f0f02ff6 | |||
cbfe9aea40 | |||
d4ae0bf2c8 | |||
36c4b2e2cf | |||
0cf8b9a1de | |||
a7b11a0f07 | |||
de2bd63927 | |||
79327510d7 | |||
4b1b6b4369 | |||
cbb6397719 |
@ -21,8 +21,9 @@ jobs:
|
||||
harbor.yadunut.dev/yadunut/yadunut.dev
|
||||
# generate Docker tags based on the following events/attributes
|
||||
tags: |
|
||||
type=sha
|
||||
type=sha,suffix=-{{ commit_date 'X' }}
|
||||
type=ref,event=branch
|
||||
type=semver,pattern={{version}}
|
||||
|
||||
- name: Login to Harbor
|
||||
uses: docker/login-action@v3
|
||||
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.zig-cache
|
31
Dockerfile
31
Dockerfile
@ -1,29 +1,12 @@
|
||||
FROM golang:1.23-alpine as builder
|
||||
FROM busybox:latest
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /app
|
||||
RUN adduser -D static
|
||||
USER static
|
||||
WORKDIR /home/static
|
||||
|
||||
# Copy and download dependencies
|
||||
COPY go.mod ./
|
||||
RUN go mod download
|
||||
COPY ./zig-out/ .
|
||||
|
||||
# Copy the source code
|
||||
COPY . .
|
||||
EXPOSE 3000
|
||||
|
||||
# Build the Go application
|
||||
RUN go build -o server .
|
||||
CMD ["busybox", "httpd", "-f", "-v", "-p", "3000"]
|
||||
|
||||
# Create a minimal runtime image
|
||||
FROM alpine:latest
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /root/
|
||||
|
||||
# Copy the compiled binary from the builder
|
||||
COPY --from=builder /app/server .
|
||||
|
||||
# Expose the application port (e.g., 8080)
|
||||
EXPOSE 8080
|
||||
|
||||
# Run the application
|
||||
CMD ["./server"]
|
||||
|
BIN
assets/fonts/MonaspaceArgonVarVF[wght,wdth,slnt].woff2
Normal file
BIN
assets/fonts/MonaspaceArgonVarVF[wght,wdth,slnt].woff2
Normal file
Binary file not shown.
BIN
assets/fonts/MonaspaceKryptonVarVF[wght,wdth,slnt].woff2
Normal file
BIN
assets/fonts/MonaspaceKryptonVarVF[wght,wdth,slnt].woff2
Normal file
Binary file not shown.
BIN
assets/fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff2
Normal file
BIN
assets/fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff2
Normal file
Binary file not shown.
BIN
assets/fonts/MonaspaceRadonVarVF[wght,wdth,slnt].woff2
Normal file
BIN
assets/fonts/MonaspaceRadonVarVF[wght,wdth,slnt].woff2
Normal file
Binary file not shown.
BIN
assets/fonts/MonaspaceXenonVarVF[wght,wdth,slnt].woff2
Normal file
BIN
assets/fonts/MonaspaceXenonVarVF[wght,wdth,slnt].woff2
Normal file
Binary file not shown.
90
assets/reset.css
Normal file
90
assets/reset.css
Normal file
@ -0,0 +1,90 @@
|
||||
/* https://piccalil.li/blog/a-more-modern-css-reset/ */
|
||||
|
||||
/* Box sizing rules */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Prevent font size inflation */
|
||||
html {
|
||||
-moz-text-size-adjust: none;
|
||||
-webkit-text-size-adjust: none;
|
||||
text-size-adjust: none;
|
||||
}
|
||||
|
||||
/* Remove default margin in favour of better control in authored CSS */
|
||||
body,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
p,
|
||||
figure,
|
||||
blockquote,
|
||||
dl,
|
||||
dd {
|
||||
margin-block-start: 0;
|
||||
margin-block-end: 0;
|
||||
}
|
||||
|
||||
/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
|
||||
ul[role='list'],
|
||||
ol[role='list'] {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* Set core body defaults */
|
||||
body {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Set shorter line heights on headings and interactive elements */
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
button,
|
||||
input,
|
||||
label {}
|
||||
|
||||
/* Balance text wrapping on headings */
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
/* A elements that don't have a class get default styles */
|
||||
a:not([class]) {
|
||||
text-decoration-skip-ink: auto;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
/* Make images easier to work with */
|
||||
img,
|
||||
picture {
|
||||
max-width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Inherit fonts for inputs and buttons */
|
||||
input,
|
||||
button,
|
||||
textarea,
|
||||
select {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
/* Make sure textareas without a rows attribute are not tiny */
|
||||
textarea:not([rows]) {
|
||||
min-height: 10em;
|
||||
}
|
||||
|
||||
/* Anything that has been anchored to should have extra scroll margin */
|
||||
:target {
|
||||
scroll-margin-block: 5ex;
|
||||
}
|
139
assets/style.css
Normal file
139
assets/style.css
Normal file
@ -0,0 +1,139 @@
|
||||
:root {
|
||||
--font-family: "Monaspace Argon", monospace;
|
||||
--measure: 100ch;
|
||||
--line-height: 1.20rem;
|
||||
|
||||
--background-color: #fbf1c7;
|
||||
--foreground-color: #282828;
|
||||
|
||||
font-family: var(--font-family);
|
||||
font-optical-sizing: auto;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
/*font-variant-numeric: tabular-nums lining-nums;*/
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
body {
|
||||
padding: var(--line-height) 1ch;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background-color: #282828;
|
||||
--foreground-color: #fbf1c7;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
width: 100%;
|
||||
line-height: var(--line-height);
|
||||
background: var(--background-color);
|
||||
color: var(--foreground-color);
|
||||
margin: calc(var(--line-height) * 3) auto;
|
||||
padding: 0 2ch;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Specify max chars on a line */
|
||||
* {
|
||||
max-inline-size: var(--measure);
|
||||
}
|
||||
|
||||
*+* {
|
||||
margin-top: var(--line-height);
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-top: 0;
|
||||
padding-left: 1ch;
|
||||
}
|
||||
|
||||
html {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
div,
|
||||
header,
|
||||
nav,
|
||||
main,
|
||||
footer {
|
||||
max-inline-size: none;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin-top: var(--line-height);
|
||||
margin-bottom: var(--line-height);
|
||||
}
|
||||
|
||||
#debug-grid {
|
||||
--color: color-mix(in srgb, var(--foreground-color) 10%, var(--background-color) 90%);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
|
||||
background-image:
|
||||
repeating-linear-gradient(var(--color) 0 1px, transparent 1px 100%),
|
||||
repeating-linear-gradient(90deg, var(--color) 0 1px, transparent 1px 100%);
|
||||
|
||||
background-size: 1ch var(--line-height);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Monaspace Neon';
|
||||
src: url('fonts/MonaspaceNeonVarVF[wght\,wdth\,slnt].woff2') format('woff2');
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-style: oblique -10deg 0deg;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Monaspace Argon';
|
||||
src: url('fonts/MonaspaceArgonVarVF[wght\,wdth\,slnt].woff2') format('woff2');
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-style: oblique -10deg 0deg;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Monaspace Krypton';
|
||||
src: url('fonts/MonaspaceKryptonVarVF[wght\,wdth\,slnt].woff2') format('woff2');
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-style: oblique -10deg 0deg;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Monaspace Radon';
|
||||
src: url('fonts/MonaspaceRadonVarVF[wght\,wdth\,slnt].woff2') format('woff2');
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-style: oblique -10deg 0deg;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Monaspace Xenon';
|
||||
src: url('fonts/MonaspaceXenonVarVF[wght\,wdth\,slnt].woff2') format('woff2');
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-style: oblique -10deg 0deg;
|
||||
}
|
19
build.zig
Normal file
19
build.zig
Normal file
@ -0,0 +1,19 @@
|
||||
const std = @import("std");
|
||||
const zine = @import("zine");
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
zine.website(b, .{
|
||||
.title = "Yadunand's Site",
|
||||
.host_url = "https://yadunut.dev",
|
||||
.content_dir_path = "content",
|
||||
.layouts_dir_path = "layouts",
|
||||
.assets_dir_path = "assets",
|
||||
.static_assets = &.{
|
||||
"fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff2",
|
||||
"fonts/MonaspaceArgonVarVF[wght,wdth,slnt].woff2",
|
||||
"fonts/MonaspaceXenonVarVF[wght,wdth,slnt].woff2",
|
||||
"fonts/MonaspaceRadonVarVF[wght,wdth,slnt].woff2",
|
||||
"fonts/MonaspaceKryptonVarVF[wght,wdth,slnt].woff2",
|
||||
},
|
||||
});
|
||||
}
|
11
build.zig.zon
Normal file
11
build.zig.zon
Normal file
@ -0,0 +1,11 @@
|
||||
.{
|
||||
.name = "Zine Website",
|
||||
.version = "0.0.0",
|
||||
.dependencies = .{
|
||||
.zine = .{
|
||||
.url = "git+https://github.com/kristoff-it/zine#7feb9e2389f015f56fc86cc90ab581b9ba3a21c6",
|
||||
.hash = "1220e1db0d9ad44ba2cb484d202cdbc2d9d62d6ec329b418d61ea13f09ab4f69df5c",
|
||||
},
|
||||
},
|
||||
.paths = .{"."},
|
||||
}
|
7
content/blog/index.smd
Normal file
7
content/blog/index.smd
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
.title = "Blogs",
|
||||
.date = @date("2024-12-14"),
|
||||
.author = "Yadunand Prem",
|
||||
.layout = "blogs.shtml",
|
||||
.draft = false,
|
||||
---
|
9
content/blog/lean.smd
Normal file
9
content/blog/lean.smd
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
.title = "Learning Lean",
|
||||
.date = @date("2024-12-26"),
|
||||
.author = "Yadunand Prem",
|
||||
.layout = "post.shtml",
|
||||
.draft = true,
|
||||
---
|
||||
|
||||
[Lean](https://lean-lang.org/) is a Programming Language and an interactive theorem prover. I'm mainly exploring this to improve my logical thinking and my mathematical proving skills.
|
29
content/index.smd
Normal file
29
content/index.smd
Normal file
@ -0,0 +1,29 @@
|
||||
---
|
||||
.title = "Yadunand's Site (WIP 🚧)",
|
||||
.date = @date("2024-12-14"),
|
||||
.author = "Yadunand Prem",
|
||||
.layout = "home.shtml",
|
||||
.draft = false,
|
||||
---
|
||||
Hi, I'm Yadunand, a software engineer currently based in 🇨🇦, previously in 🇭🇰,🇦🇺,🇸🇬. I'm interested in how
|
||||
companies build things that scale, and how infrastructure works in general. This site is built on the exploration of
|
||||
that. Most of my work (including [this site](https://git.yadunut.dev/yadunut/yadunut.dev), and the [infrastructure](https://git.yadunut.dev/yadunut/homelab)) can be found on my [gitea](https://git.yadunut.dev/yadunut)
|
||||
|
||||
## Currently
|
||||
- Software Engineer at [Endor Health](https://endorhealth.com)
|
||||
- React Native, Typescript
|
||||
- Python, Flask
|
||||
- Year 3 student at [National University of Singapore](https://www.nus.edu.sg/)
|
||||
- Exchange Student at [University of Toronto](https://www.utoronto.ca/)
|
||||
|
||||
## Previously
|
||||
- Technology Intern at [Marshall Wace](https://www.mwam.com/)
|
||||
- Python, FastAPI
|
||||
- React, Typescript
|
||||
- K8s, flux, grafana, prometheus
|
||||
- Software Engineer at [Undertide](https://www.undertide.co/)
|
||||
- React Native, Graphql, Typescript
|
||||
|
||||
## Contact Me
|
||||
|
||||
I'm always happy to chat, feel free to reach out to me a @yadunut on (Twitter, Instagram, Telegram) or on [email](mailto:me@yadunut.com)
|
7
content/sitemap.smd
Normal file
7
content/sitemap.smd
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
.title = "Sitemap",
|
||||
.date = @date("2024-12-14"),
|
||||
.author = "Yadunand Prem",
|
||||
.layout = "sitemap.shtml",
|
||||
.draft = false,
|
||||
---
|
@ -20,11 +20,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1731890469,
|
||||
"narHash": "sha256-D1FNZ70NmQEwNxpSSdTXCSklBH1z2isPR84J6DQrJGs=",
|
||||
"lastModified": 1734126203,
|
||||
"narHash": "sha256-0XovF7BYP50rTD2v4r55tR5MuBLet7q4xIz6Rgh3BBU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "5083ec887760adfe12af64830a66807423a859a7",
|
||||
"rev": "71a6392e367b08525ee710a93af2e80083b5b3e2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -15,7 +15,7 @@
|
||||
devShells = {
|
||||
default = pkgs.mkShell {
|
||||
buildInputs = with pkgs;[
|
||||
go gopls gotools go-tools
|
||||
zig
|
||||
];
|
||||
};
|
||||
};
|
||||
|
17
layouts/blogs.shtml
Normal file
17
layouts/blogs.shtml
Normal file
@ -0,0 +1,17 @@
|
||||
<extend template="base.shtml">
|
||||
<title id="title" :text="$site.title"></title>
|
||||
<div id="main">
|
||||
<h1 :text="$page.title"></h1>
|
||||
<ul :loop="$page.subpages()">
|
||||
<li>
|
||||
<a href="$loop.it.link()" :text="$loop.it.title"></a>
|
||||
<div :if="$loop.it.isSection()">
|
||||
<ul :loop="$loop.it.subpages()">
|
||||
<li>
|
||||
<a href="$loop.it.link()" :text="$loop.it.title"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
6
layouts/home.shtml
Normal file
6
layouts/home.shtml
Normal file
@ -0,0 +1,6 @@
|
||||
<extend template="base.shtml">
|
||||
<title id="title" :text="$site.title"></title>
|
||||
<div id="main">
|
||||
<h1 :text="$page.title"></h1>
|
||||
<div :html="$page.content()"></div>
|
||||
</div>
|
14
layouts/post.shtml
Normal file
14
layouts/post.shtml
Normal file
@ -0,0 +1,14 @@
|
||||
<extend template="base.shtml">
|
||||
<title id="title" :text="$site.title"></title>
|
||||
<div id="main">
|
||||
<h2 :text="$page.title"></h2>
|
||||
<h3>by
|
||||
<span :text="$page.author"></span></h3>
|
||||
<h4>
|
||||
Posted on:
|
||||
<span
|
||||
:text="$page.date.format('January 02, 2006')"
|
||||
></span>
|
||||
</h4>
|
||||
<div :html="$page.content()"></div>
|
||||
</div>
|
17
layouts/sitemap.shtml
Normal file
17
layouts/sitemap.shtml
Normal file
@ -0,0 +1,17 @@
|
||||
<extend template="base.shtml">
|
||||
<title id="title" :text="$site.title"></title>
|
||||
<div id="main">
|
||||
<h1 :text="$page.title"></h1>
|
||||
<ul :loop="$page.parentSection().subpages()">
|
||||
<li>
|
||||
<a href="$loop.it.link()" :text="$loop.it.title"></a>
|
||||
<div :if="$loop.it.isSection()">
|
||||
<ul :loop="$loop.it.subpages()">
|
||||
<li>
|
||||
<a href="$loop.it.link()" :text="$loop.it.title"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
20
layouts/templates/base.shtml
Normal file
20
layouts/templates/base.shtml
Normal file
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title id="title"><super></title>
|
||||
<link rel="stylesheet" type="text/css" href="$site.asset('reset.css').link()">
|
||||
<link rel="stylesheet" type="text/css" href="$site.asset('style.css').link()">
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="/">Home</a>
|
||||
<a href="$site.page('blog').link()">Blog</a>
|
||||
<a href="$site.page('sitemap').link()">Sitemap</a>
|
||||
</nav>
|
||||
<div id="main">
|
||||
<super>
|
||||
</div>
|
||||
<div id="debug-grid"></div>
|
||||
</body>
|
||||
</html>
|
16
main.go
16
main.go
@ -1,16 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"git.yadunut.dev/yadunut/yadunut.dev/site"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := site.NewConfig(slog.LevelDebug, 8080)
|
||||
c.Logger.Info("Starting server")
|
||||
if err := site.Run(c); err != nil {
|
||||
c.Logger.Error(fmt.Sprintf("failed with error %s", err))
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
package site
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type counter struct {
|
||||
hits map[string]int
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
type handler struct {
|
||||
logger *slog.Logger
|
||||
requestsCounter *counter
|
||||
}
|
||||
|
||||
func newHandler(logger *slog.Logger) *handler {
|
||||
return &handler{
|
||||
logger: logger,
|
||||
requestsCounter: &counter{hits: make(map[string]int)},
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) LoggingMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
h.logger.Debug("Received request", "path", r.URL.Path)
|
||||
next.ServeHTTP(w, r)
|
||||
h.logger.Debug("Finished Request", "path", r.URL.Path)
|
||||
})
|
||||
}
|
||||
|
||||
func (h *handler) RequestsCounterMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
h.requestsCounter.mu.Lock()
|
||||
h.requestsCounter.hits[r.URL.Path] += 1
|
||||
h.requestsCounter.mu.Unlock()
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func (h *handler) Ping(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "Pong")
|
||||
}
|
||||
func (h *handler) Index(w http.ResponseWriter, r *http.Request) {
|
||||
h.logger.Info(r.URL.Path)
|
||||
|
||||
if template, isOk := templates[r.URL.Path]; isOk {
|
||||
h.logger.Info("Found template")
|
||||
template.ExecuteTemplate(w, "base", nil)
|
||||
} else {
|
||||
h.logger.Info("default template")
|
||||
templates["index.html"].ExecuteTemplate(w, "base", nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) FileServer(w http.ResponseWriter, r *http.Request) {
|
||||
h.logger.Info("handled by file server router")
|
||||
http.FileServer(http.FS(staticContent)).ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (h *handler) Metrics(w http.ResponseWriter, r *http.Request) {
|
||||
h.requestsCounter.mu.Lock()
|
||||
defer h.requestsCounter.mu.Unlock()
|
||||
for path, hits := range h.requestsCounter.hits {
|
||||
fmt.Fprintf(w, "http_requests_total{handler=\"%s\"} %d\n", path, hits)
|
||||
}
|
||||
}
|
||||
func (h *handler) Healthz(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, "Ok")
|
||||
}
|
||||
|
||||
func (h *handler) NotFound(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Page Not Found", http.StatusNotFound)
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package site
|
||||
|
||||
import "net/http"
|
||||
|
||||
func middlewares(h *handler, next http.Handler) http.Handler {
|
||||
return h.LoggingMiddleware(h.RequestsCounterMiddleware(next))
|
||||
}
|
||||
|
||||
func createRoutes(h *handler) map[string]http.Handler {
|
||||
routes := map[string]http.Handler{
|
||||
"/static/": middlewares(h, http.HandlerFunc(h.FileServer)),
|
||||
"/": middlewares(h, http.HandlerFunc(h.Index)),
|
||||
"/ping": middlewares(h, http.HandlerFunc(h.Ping)),
|
||||
"/metrics": middlewares(h, http.HandlerFunc(h.Metrics)),
|
||||
"/healthz": middlewares(h, http.HandlerFunc(h.Healthz)),
|
||||
}
|
||||
return routes
|
||||
}
|
||||
|
||||
func newRouter(handler *handler) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
for pattern, handler := range createRoutes(handler) {
|
||||
mux.Handle(pattern, handler)
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if h, pattern := mux.Handler(r); pattern != "" {
|
||||
h.ServeHTTP(w, r)
|
||||
} else {
|
||||
middlewares(handler, http.HandlerFunc(handler.NotFound)).ServeHTTP(w, r)
|
||||
}
|
||||
})
|
||||
}
|
26
site/site.go
26
site/site.go
@ -1,26 +0,0 @@
|
||||
package site
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Logger *slog.Logger
|
||||
Port int
|
||||
}
|
||||
|
||||
func NewConfig(logLevel slog.Level, port int) Config {
|
||||
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug}))
|
||||
return Config{
|
||||
Logger: logger,
|
||||
Port: port,
|
||||
}
|
||||
}
|
||||
|
||||
func Run(c Config) error {
|
||||
h := newHandler(c.Logger)
|
||||
return http.ListenAndServe(fmt.Sprintf(":%d", c.Port), newRouter(h))
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
:root {
|
||||
--font-family: "Comic Mono";
|
||||
--line-height: 1.2rem;
|
||||
--font-weight-normal: 500;
|
||||
--font-weight-medium: 600;
|
||||
--font-weight-bold: 800;
|
||||
|
||||
font-family: var(--font-family), monospace;
|
||||
font-weight: var(--font-weight-normal);
|
||||
font-size: 16px;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
line-height: var(--line-height);
|
||||
max-width: 100ch;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: calc(var(--line-height) * 2) 0 var(--line-height) 0;
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
margin-bottom: calc(var(--line-height) * 2);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
#grid {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-image: linear-gradient(to right, #ccc 1px, transparent 1px),
|
||||
linear-gradient(to bottom, #ccc 1px, transparent 1px);
|
||||
background-size: 1ch var(--line-height); /* Adjust grid size */
|
||||
background-position: top left;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: var(--line-height);
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html,
|
||||
body,
|
||||
div,
|
||||
span,
|
||||
applet,
|
||||
object,
|
||||
iframe,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
blockquote,
|
||||
pre,
|
||||
a,
|
||||
abbr,
|
||||
acronym,
|
||||
address,
|
||||
big,
|
||||
cite,
|
||||
code,
|
||||
del,
|
||||
dfn,
|
||||
em,
|
||||
img,
|
||||
ins,
|
||||
kbd,
|
||||
q,
|
||||
s,
|
||||
samp,
|
||||
small,
|
||||
strike,
|
||||
strong,
|
||||
sub,
|
||||
sup,
|
||||
tt,
|
||||
var,
|
||||
b,
|
||||
u,
|
||||
i,
|
||||
center,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ol,
|
||||
ul,
|
||||
li,
|
||||
fieldset,
|
||||
form,
|
||||
label,
|
||||
legend,
|
||||
table,
|
||||
caption,
|
||||
tbody,
|
||||
tfoot,
|
||||
thead,
|
||||
tr,
|
||||
th,
|
||||
td,
|
||||
article,
|
||||
aside,
|
||||
canvas,
|
||||
details,
|
||||
embed,
|
||||
figure,
|
||||
figcaption,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
output,
|
||||
ruby,
|
||||
section,
|
||||
summary,
|
||||
time,
|
||||
mark,
|
||||
audio,
|
||||
video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol,
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote,
|
||||
q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before,
|
||||
blockquote:after,
|
||||
q:before,
|
||||
q:after {
|
||||
content: "";
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package site
|
||||
|
||||
import (
|
||||
"embed"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/fs"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var templates map[string]*template.Template
|
||||
|
||||
func init() {
|
||||
templates = make(map[string]*template.Template)
|
||||
fs.WalkDir(templateContent, "templates", func(p string, d fs.DirEntry, err error) error {
|
||||
if d.IsDir() || !strings.HasSuffix(p, ".html") {
|
||||
return nil
|
||||
}
|
||||
basePath := path.Base(p)
|
||||
templates[basePath] = template.Must(template.ParseFS(templateContent, p, "templates/_layout.html.tmpl"))
|
||||
fmt.Println(path.Base(p))
|
||||
return nil
|
||||
})
|
||||
fmt.Printf("successfully parsed templates: ")
|
||||
for k, t := range templates {
|
||||
fmt.Printf("%s: %s \n", k, t.Name())
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
//go:embed templates/*
|
||||
var templateContent embed.FS
|
||||
|
||||
//go:embed static/*
|
||||
var staticContent embed.FS
|
@ -1,15 +0,0 @@
|
||||
{{ define "base" }}
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/reset.css" />
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/comic-mono@0.0.1/index.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/main.css" />
|
||||
<title>Yadunand's Site 🚧</title>
|
||||
</head>
|
||||
<body>
|
||||
{{ template "content" .}}
|
||||
<div id="grid"></div>
|
||||
</body>
|
||||
</html>
|
||||
{{ end }}
|
@ -1,12 +0,0 @@
|
||||
{{ define "content" }}
|
||||
<h1>Yadunand's Site WIP 🚧</h1>
|
||||
<p>Body</p>
|
||||
<h2>Header 2</h2>
|
||||
<p>Body</p>
|
||||
<h3>Header 3</h3>
|
||||
<p>Body</p>
|
||||
<h4>Header 4</h4>
|
||||
<p>Body</p>
|
||||
<h5>Header 5</h5>
|
||||
<p></p>
|
||||
{{ end }}
|
23
zig-out/blog/index.html
Normal file
23
zig-out/blog/index.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title id="title">Yadunand's Site</title>
|
||||
<link rel="stylesheet" type="text/css" href="/reset.css">
|
||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="/">Home</a>
|
||||
<a href="/blog/">Blog</a>
|
||||
<a href="/sitemap/">Sitemap</a>
|
||||
</nav>
|
||||
<div id="main">
|
||||
|
||||
<h1>Blogs</h1>
|
||||
<ul></ul>
|
||||
|
||||
</div>
|
||||
<div id="debug-grid"></div>
|
||||
</body>
|
||||
</html>
|
BIN
zig-out/fonts/MonaspaceArgonVarVF[wght,wdth,slnt].woff2
Normal file
BIN
zig-out/fonts/MonaspaceArgonVarVF[wght,wdth,slnt].woff2
Normal file
Binary file not shown.
BIN
zig-out/fonts/MonaspaceKryptonVarVF[wght,wdth,slnt].woff2
Normal file
BIN
zig-out/fonts/MonaspaceKryptonVarVF[wght,wdth,slnt].woff2
Normal file
Binary file not shown.
BIN
zig-out/fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff2
Normal file
BIN
zig-out/fonts/MonaspaceNeonVarVF[wght,wdth,slnt].woff2
Normal file
Binary file not shown.
BIN
zig-out/fonts/MonaspaceRadonVarVF[wght,wdth,slnt].woff2
Normal file
BIN
zig-out/fonts/MonaspaceRadonVarVF[wght,wdth,slnt].woff2
Normal file
Binary file not shown.
BIN
zig-out/fonts/MonaspaceXenonVarVF[wght,wdth,slnt].woff2
Normal file
BIN
zig-out/fonts/MonaspaceXenonVarVF[wght,wdth,slnt].woff2
Normal file
Binary file not shown.
23
zig-out/index.html
Normal file
23
zig-out/index.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title id="title">Yadunand's Site</title>
|
||||
<link rel="stylesheet" type="text/css" href="/reset.css">
|
||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="/">Home</a>
|
||||
<a href="/blog/">Blog</a>
|
||||
<a href="/sitemap/">Sitemap</a>
|
||||
</nav>
|
||||
<div id="main">
|
||||
|
||||
<h1>Yadunand's Site (WIP 🚧)</h1>
|
||||
<div><p>Hi, I’m Yadunand, a software engineer currently based in 🇨🇦, previously in 🇭🇰,🇦🇺,🇸🇬. I’m interested in how companies build things that scale, and how infrastructure works in general. This site is built on the exploration of that. Most of my work (including <a href="https://git.yadunut.dev/yadunut/yadunut.dev" target="_blank">this site</a>, and the <a href="https://git.yadunut.dev/yadunut/homelab" target="_blank">infrastructure</a>) can be found on my <a href="https://git.yadunut.dev/yadunut" target="_blank">gitea</a></p><h2>Currently</h2><ul><li>Software Engineer at <a href="https://endorhealth.com" target="_blank">Endor Health</a><ul><li>React Native, Typescript</li><li>Python, Flask</li></ul></li><li>Year 3 student at <a href="https://www.nus.edu.sg/" target="_blank">National University of Singapore</a></li><li>Exchange Student at <a href="https://www.utoronto.ca/" target="_blank">University of Toronto</a></li></ul><h2>Previously</h2><ul><li>Technology Intern at <a href="https://www.mwam.com/" target="_blank">Marshall Wace</a><ul><li>Python, FastAPI</li><li>React, Typescript</li><li>K8s, flux, grafana, prometheus</li></ul></li><li>Software Engineer at <a href="https://www.undertide.co/" target="_blank">Undertide</a><ul><li>React Native, Graphql, Typescript</li></ul></li></ul><h2>Contact Me</h2><p>I’m always happy to chat, feel free to reach out to me a @yadunut on (Twitter, Instagram, Telegram) or on <a href="mailto:me@yadunut.com" target="_blank">email</a></p></div>
|
||||
|
||||
</div>
|
||||
<div id="debug-grid"></div>
|
||||
</body>
|
||||
</html>
|
90
zig-out/reset.css
Normal file
90
zig-out/reset.css
Normal file
@ -0,0 +1,90 @@
|
||||
/* https://piccalil.li/blog/a-more-modern-css-reset/ */
|
||||
|
||||
/* Box sizing rules */
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Prevent font size inflation */
|
||||
html {
|
||||
-moz-text-size-adjust: none;
|
||||
-webkit-text-size-adjust: none;
|
||||
text-size-adjust: none;
|
||||
}
|
||||
|
||||
/* Remove default margin in favour of better control in authored CSS */
|
||||
body,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
p,
|
||||
figure,
|
||||
blockquote,
|
||||
dl,
|
||||
dd {
|
||||
margin-block-start: 0;
|
||||
margin-block-end: 0;
|
||||
}
|
||||
|
||||
/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
|
||||
ul[role='list'],
|
||||
ol[role='list'] {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* Set core body defaults */
|
||||
body {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Set shorter line heights on headings and interactive elements */
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
button,
|
||||
input,
|
||||
label {}
|
||||
|
||||
/* Balance text wrapping on headings */
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
/* A elements that don't have a class get default styles */
|
||||
a:not([class]) {
|
||||
text-decoration-skip-ink: auto;
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
/* Make images easier to work with */
|
||||
img,
|
||||
picture {
|
||||
max-width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Inherit fonts for inputs and buttons */
|
||||
input,
|
||||
button,
|
||||
textarea,
|
||||
select {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
/* Make sure textareas without a rows attribute are not tiny */
|
||||
textarea:not([rows]) {
|
||||
min-height: 10em;
|
||||
}
|
||||
|
||||
/* Anything that has been anchored to should have extra scroll margin */
|
||||
:target {
|
||||
scroll-margin-block: 5ex;
|
||||
}
|
35
zig-out/sitemap/index.html
Normal file
35
zig-out/sitemap/index.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title id="title">Yadunand's Site</title>
|
||||
<link rel="stylesheet" type="text/css" href="/reset.css">
|
||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href="/">Home</a>
|
||||
<a href="/blog/">Blog</a>
|
||||
<a href="/sitemap/">Sitemap</a>
|
||||
</nav>
|
||||
<div id="main">
|
||||
|
||||
<h1>Sitemap</h1>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/sitemap/">Sitemap</a>
|
||||
<div></div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/blog/">Blogs</a>
|
||||
<div>
|
||||
<ul></ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div id="debug-grid"></div>
|
||||
</body>
|
||||
</html>
|
139
zig-out/style.css
Normal file
139
zig-out/style.css
Normal file
@ -0,0 +1,139 @@
|
||||
:root {
|
||||
--font-family: "Monaspace Argon", monospace;
|
||||
--measure: 100ch;
|
||||
--line-height: 1.20rem;
|
||||
|
||||
--background-color: #fbf1c7;
|
||||
--foreground-color: #282828;
|
||||
|
||||
font-family: var(--font-family);
|
||||
font-optical-sizing: auto;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
/*font-variant-numeric: tabular-nums lining-nums;*/
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
body {
|
||||
padding: var(--line-height) 1ch;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background-color: #282828;
|
||||
--foreground-color: #fbf1c7;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
width: 100%;
|
||||
line-height: var(--line-height);
|
||||
background: var(--background-color);
|
||||
color: var(--foreground-color);
|
||||
margin: calc(var(--line-height) * 3) auto;
|
||||
padding: 0 2ch;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Specify max chars on a line */
|
||||
* {
|
||||
max-inline-size: var(--measure);
|
||||
}
|
||||
|
||||
*+* {
|
||||
margin-top: var(--line-height);
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-top: 0;
|
||||
padding-left: 1ch;
|
||||
}
|
||||
|
||||
html {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
div,
|
||||
header,
|
||||
nav,
|
||||
main,
|
||||
footer {
|
||||
max-inline-size: none;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin-top: var(--line-height);
|
||||
margin-bottom: var(--line-height);
|
||||
}
|
||||
|
||||
#debug-grid {
|
||||
--color: color-mix(in srgb, var(--foreground-color) 10%, var(--background-color) 90%);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
|
||||
background-image:
|
||||
repeating-linear-gradient(var(--color) 0 1px, transparent 1px 100%),
|
||||
repeating-linear-gradient(90deg, var(--color) 0 1px, transparent 1px 100%);
|
||||
|
||||
background-size: 1ch var(--line-height);
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Monaspace Neon';
|
||||
src: url('fonts/MonaspaceNeonVarVF[wght\,wdth\,slnt].woff2') format('woff2');
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-style: oblique -10deg 0deg;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Monaspace Argon';
|
||||
src: url('fonts/MonaspaceArgonVarVF[wght\,wdth\,slnt].woff2') format('woff2');
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-style: oblique -10deg 0deg;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Monaspace Krypton';
|
||||
src: url('fonts/MonaspaceKryptonVarVF[wght\,wdth\,slnt].woff2') format('woff2');
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-style: oblique -10deg 0deg;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Monaspace Radon';
|
||||
src: url('fonts/MonaspaceRadonVarVF[wght\,wdth\,slnt].woff2') format('woff2');
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-style: oblique -10deg 0deg;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Monaspace Xenon';
|
||||
src: url('fonts/MonaspaceXenonVarVF[wght\,wdth\,slnt].woff2') format('woff2');
|
||||
font-weight: 100 900;
|
||||
font-stretch: 75% 125%;
|
||||
font-style: oblique -10deg 0deg;
|
||||
}
|
Loading…
Reference in New Issue
Block a user