Add my content
All checks were successful
Build OCI Image / docker (push) Successful in 36s

This commit is contained in:
Yadunand Prem 2025-08-05 11:51:37 +08:00
parent cc57dee334
commit 705e1e3dab
18 changed files with 150 additions and 383 deletions

81
CLAUDE.md Normal file
View File

@ -0,0 +1,81 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a static website built with [Zine](https://zine-ssg.io/), a static site generator written in Zig. The site uses:
- **SuperMD (.smd)** for content pages - a Markdown superset with embedded templating
- **SuperHTML (.shtml)** for layout templates - HTML with templating extensions
- **Nix** for development environment and dependency management
## Development Commands
### Development Server
```bash
# Start development server with live reload (default: localhost:1990)
zine
# Start with custom host/port
zine --port 8080 --host 0.0.0.0
# Include draft pages
zine --drafts
```
### Build for Production
```bash
# Generate static site for deployment
zine release
```
### Environment Setup
```bash
# Enter development shell with zine available
nix develop
```
## Project Structure
### Content Files (.smd)
- `content/` - All site content in SuperMD format
- `index.smd` - Homepage
- `about.smd` - About page
- `blog/` - Blog posts and index
- `devlog/` - Microblog entries
### Layout Templates (.shtml)
- `layouts/` - SuperHTML templates
- `templates/base.shtml` - Base template with site navigation
- `index.shtml`, `page.shtml`, `post.shtml` - Page-specific layouts
- `blog.shtml`, `devlog.shtml` - Section layouts
- `*.xml` - RSS feed templates
### Configuration
- `zine.ziggy` - Site configuration (title, URLs, asset paths)
- `flake.nix` - Nix development environment with Zine binary
### Assets
- `assets/` - Static assets (CSS, JS, images)
- Includes math rendering (Temml) and syntax highlighting
## Architecture Notes
### Content Types
1. **Pages** - Individual content files with frontmatter and layout assignment
2. **Blog** - Traditional blog with separate pages per post
3. **Devlog** - Microblog format with multiple entries on single page
### Templating System
- Uses Scripty expression language for logic
- SuperHTML templates extend base template via `<extend template="base.shtml">`
- Content rendered via `$page.content()`, metadata via `$page.title`, etc.
- Site-wide variables available via `$site.*`
### Asset Handling
- Static assets referenced via `$site.asset('filename').link()`
- Page-specific assets stored alongside content files
- CSS and JS assets included in base template
The development server automatically rebuilds on file changes with configurable debounce timing.

View File

@ -1,56 +0,0 @@
---
.title = "About",
.date = @date("1990-01-01T00:00:00"),
.author = "Sample Author",
.layout = "index.shtml",
.draft = false,
---
## About Zine
Zine is an MIT-licensed project created by [Loris Cro](https://kristoff.it) and
other contributors listed on the [official repository](https://github.com/kristoff-it/zine/contributors).
Zine is inspired by [Hugo](https://gohugo.io) but features an entirely custom set
of authoring languages:
- [Scripty](https://zine-ssg.io/docs/scripty/) is the small expression
language that both SuperHTML and SuperMD share to express templating logic.
- [SuperHTML](https://zine-ssg.io/docs/superhtml/) is the HTML templating
language used by Zine. Unlike most `{{curly braced}}` templating languages,
SuperHTML uses valid HTML syntax to express the templating logic, adding only
minor extensions to normal HTML.
Thanks to this approach, it offers instant
syntax checking and autoformatting via [a CLI tool](https://github.com/kristoff-it/superhtml) as well as Language Server support ([VScode Extension](https://marketplace.visualstudio.com/items?itemName=LorisCro.super)).
># [NOTE]($block)
>The correct file extension for SuperHTML templates is `.shtml`.
- [SuperMD](https://zine-ssg.io/docs/supermd/) is a superset of Markdown
that, instead of relying on inline HTML, offers new constructs for expressing
content embeds without pulling into your content needless layouting concerns.
A CLI tool and language server for SuperMD is in the works.
># [NOTE]($block)
>The correct file extension for SuperMD pages is `.smd`.
## Zine is alpha software
Zine is not yet complete. The main functionality is present and you will be able
to build even moderately complex static websites without issue.
That said using Zine today does imply participating in the development process
to some degree, which usually means inquiring about the development status of
a feature you need, or reporting a bug.
Here are some quicklinks related to Zine:
- Official Website: https://zine-ssg.io/
- Source Code: https://github.com/kristoff-it/zine/
- Discord: https://discord.com/invite/B73sGxF

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

View File

@ -1,110 +0,0 @@
---
.title = "First Post: What's A Zine?",
.date = @date("1990-01-01T00:00:00"),
.author = "Sample Author",
.layout = "post.shtml",
.draft = false,
---
This is a sample first post for your blog.
This post is defined in `content/blog/first-post/` and contains the following
files:
- `index.smd`
- `fanzine.jpg`
Another interesting thing about this post is that it uses the `layouts/post.shtml`
template which adds at the bottom page navigation within the blog section.
Enough about Zine, let's talk about zines.
## Fanzines
A zine (short for *fanzine*, from "fan" + "magazine") is a non-professional
publication created by people that want to express themselves in paper form,
usually in relation to a cultural phenomenon of some kind.
[An example of zine from 1976.](<$image.asset("fanzine.jpg").alt("A photo of a black and white flyer. The main title reads 'A night of pure energy' and the rest of the page contains a mix of pictures of guitarists interleaved with other text snippets, some seemingly taken from a professional publication of some kind, and some handwritten to announce concert night dates, presumably for the musicians in the picture.")>)
## Zines in the digital era
In the digital age, some of the cultural impetus behind zines got redirected to
personal blogs and similar digital, non-professional publications. The 90's and
early 00's are famous for their whacky websites full of clip art, wordart text
and "under construction" animated gifs.
This initial organic exploration didn't last for too long as the rise of social
media diverted a lot of self-expression energy towards walled gardens, a change
that was also fueled by the much tighter and intense feedback loop that those
platform enable.
In the 90's the stongest dopamine hit you could get was adding a visit counter
to your altavista website and watch it go up, slowly, mostly because of your own
accesses. In modern times views are almost meaningless and interactions such as
*likes*, *retweets* and *comments* provide much stronger positive feedback.
An unfortunate side effect of this new cultural wave centered around social media
is that not only you end up gifting your content to platform owners, but you also
participate in a system where the *language* of the social media site shapes your
thoughts and experience in specific, and often user-hostile, ways.
Art, just like liquids, takes the shape of the container you put it in. A mobile
game that lives off of in app purchases will never be truly great because of the
tension between making the game entertaining enough to keep players engaged, and
the need to make it boring enough so that they will want to buy upgrades to make
the game more fun.
Similarly, self-expression on Twitter is encouraged to take the shape of short,
hyperbolic hot takes that forgo nuance in order to create catchy quips that can
be used for hasty decision making.
Likewise, [corpowave]($text.attrs('wave')) never goes out of style on LinkedIn.
Spend enough time in there and you will become a character from Severance.
## We're not in 1990 anymore
Despite all the issues with social media, there is no point in thinking of the
90's as a better time. It was not. And despite the winks at the past, Zine is
not a tool for indulging in nostalgia.
**The goal is to make art**: the act of inducing a change in others through
our self-expression.
You could argue that the 90's excelled at self-expression, but in doing so you
would also have to accept that social media is infinitely more effective at
inducing change in others (albeit at the expense of freedom of expression).
Once you realize that, the path forward is clear:
1. Own your content.
2. Create new social systems that optimize for creating art over engagement.
Owning your content means that you will be unaffected by enshittification of
platforms that would otherwise keep your data hostage. It also is the single
most effective thing you can do as an individual to take power away from
platforms, all while protecting your own immediate interests.
Creation of new social systems is a *slightly more hairy* problem than self
hosting a static website, but it's something that can be done. Over the years
we've had plenty of social outlets that have allowed people to socialize through
their homemade games, music, drawings, fanfics, etc; and chances are that we
have yet many more of these outlets ahead of us to create.
Zine gives you a small puzzle piece to help you inch closer toward a better
future, partially by providing you with a new iteration over tried and true
patterns (e.g. by facilitating content creation by separating content from
layouting concerns as much as possible), and also by being a bit experimental
with the concept of a devlog, something that you wouldn't normally expect to
find on a static website.
Lastly, Zine makes sure your content (both blog and devlog, but also any
other content format you might come up with yourself) is available via RSS
syndication. RSS feeds are far from a winning technology in the fight against
the ebb and *enshitty*flow of social media, but they are another small puzzle
piece that costs nothing to maintain and that might turn out to be critical once
enough other preconditions are met.
With that in mind, **go make art with your words**.
-- Loris

View File

@ -1,40 +1,14 @@
---
.title = "Blog",
.date = @date("1990-01-01T00:00:00"),
.author = "Sample Author",
.date = @date("2025-08-05"),
.author = "Yadunand Prem",
.layout = "blog.shtml",
.alternatives = [{
.alternatives = [{
.name = "rss",
.layout = "blog.xml",
.layout = "blog.xml",
.output = "index.xml",
}],
.draft = false,
---
---
This page defines the blog section and lists all posts in it.
A "site section" in Zine is a group of pages that form a logical subtree of the
website. It's related to directory structure, but it's not an entirely 1:1 mapping.
What defines a site section in Zine is the presence of `index.smd` files. You
can learn more [in the official Zine docs](https://zine-ssg.io/docs/).
Take also a look at `layouts/blog.shtml` to get an idea of how to render a page
list in a SuperHTML template.
The blog section also has an [RSS feed]($link.alternative('rss')).
In Zine, RSS feeds are considered "alternative" versions of an existing page. In
concrete defines the blog section and that lists all pages in it, is rendered in
two versions: HTML for human readers, and XML for RSS readers.
This is the SuperMD frontmatter code that defines the RSS feed:
```ziggy
.alternatives = [{
.name = "rss",
.layout = "rss.xml",
.output = "index.xml",
}],
```
[(btw syntax highlighting is done statically in Zine, no need for javascript libraries, unless you want to)]($text.attrs('small'))
The blog section has an [RSS feed]($link.alternative('rss')).

View File

@ -1,10 +1,10 @@
---
.title = "Second Post",
.date = @date("1990-01-02T00:00:00"),
.date = @date("1990-01-01"),
.author = "Sample Author",
.layout = "post.shtml",
.draft = false,
---
.draft = true,
---
This second post is mainly here to show you that you can also create single file
posts for convenience. The first post contains more interesting content.
@ -25,4 +25,3 @@ F(\omega) &= \int_{-\infty}^\infty f(t) \div (-1)^{2 \omega t} \mathrm{d}t \\
This: [`(-1)^x = \cos(\pi x) + i\sin(\pi x)`]($mathtex) is an inline equation
instead!

View File

@ -1,18 +0,0 @@
---
.title = "Devlog - 1989",
.date = @date("1989-01-01T00:00:00"),
.author = "Sample Author",
.layout = "devlog.shtml",
.draft = false,
---
[]($section.id('about'))
## About this Devlog
This is a non-exhaustive, curated list of changes meant to help users quickly see what has improved since they last checked.
You can [subscribe the latest devlog via RSS]($link.page('devlog').alternative('rss')).
This page lists entries for the year 1989, for past or future entries consult the
[devlog archive](/devlog/).
## [Hello 1989]($section.id("1989-01-01T00:00:00"))
This is a sample entry.

View File

@ -1,38 +0,0 @@
---
.title = "Devlog - 1990",
.date = @date("1990-01-01T00:00:00"),
.author = "Sample Author",
.layout = "devlog.shtml",
.draft = false,
---
[]($section.id('about'))
## About this Devlog
This is where you should describe to your users what your devlog is about.
Refer to the corresponding section in the home page to learn more about devlogs.
For example this is how the Zine devlog describes itself:
> This is a non-exhaustive, curated list of changes meant to help users quickly see what has improved since they last checked.
>
> You can [subscribe to this page via RSS]($link.page('devlog').alternative('rss')).
>
> This page lists entries for the current year, for past entries consult the
[devlog archive](/devlog/).
Feel free to tweak it to your specific use case or replace it entirely as you
see fit.
Regardless of what you decide, you might want to make sure you preserve the
links to the RSS feed and to the devlog archive from the copy above.
## [Third Entry]($section.id("1990-01-03T00:00:00"))
This is the third entry.
## [Second Entry]($section.id("1990-01-02T00:00:00"))
This is the second entry.
## [Hello Zine]($section.id("1990-01-01T00:00:00"))
This is the first entry in this year's devlog created with
[Zine](https://zine-ssg.io)!

View File

@ -1,32 +0,0 @@
---
.title = "Devlog Archive",
.date = @date("1990-01-01T00:00:00"),
.author = "Sample Author",
.layout = "devlog-archive.shtml",
.alternatives = [{
.name = "rss",
.layout = "devlog.xml",
.output = "index.xml",
}],
.draft = false,
---
This page lists all the devlog years that are present on this site.
Note how the top navigation menu doesn't link to this page, but instead links
to the latest devlog year directly.
The reason for adopting this structure is to make sure that links that exist in
the wild to entries to our devlog don't become invalidated when a new year comes
around and we rotate the devlog feed.
Devlog rotation ensures that you don't have a single page that grows
indefinitely, eventually compromising your editing expreience and worsening your
user's browsing experience. You can use any arbitrary policy (even deleting old
entries if you are fine with having a more ephemeral devlog), but cutting them
by year is a good default option.
When rotating a devlog all you have to do is create a new page with a newer
date set in the frontmatter `date` field, and update the page description to let
people know that this page is not the current year's devlog anymore.
The latest devlog year is also available [via RSS feed]($link.alternative('rss')).

View File

@ -1,88 +1,29 @@
---
.title = "Homepage",
.date = @date("1990-01-01T00:00:00"),
.author = "Sample Author",
.title = "Yadunand's Site (WIP 🚧)",
.date = @date("2025-08-05"),
.author = "Yadunand Prem",
.layout = "index.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)
This sample website showcases:
## Currently
- Year 4 student at [National University of Singapore](https://www.nus.edu.sg/)
- CS4212 (Compiler Design)
- CS3223 (Database Systems Implementation)
- CS3231 (Theory of Computation)
- A couple simple pages
- `content/index.smd`
- `content/about.smd`
- A blog
- `content/blog/index.smd`
- `content/blog/first-post/index.smd`
- `content/blog/second-post.smd`
- A devlog
- `content/devlog/index.smd`
- `content/devlog/1990.smd`
- `content/devlog/1989.smd`
## Previously
- Software Engineer at [Endor Health](https://endorhealth.com)
- React Native, Typescript
- Python, Flask
- 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
## About Devlogs
While a blog has each entry be a separate page, a devlog is one single page with
a list of smaller entries in it, making it a form of microblogging. The relative
RSS feed will generate a separate item per devlog entry, creating a
"twitter-like" feed.
This can be a useful pattern for thoughts that are too small for a full blog post
so consider giving it a try!
The name "devlog" comes from the fact that this kind of microblogging feed works
well when you have an open source project and you want to give small updates to
your users, but it might work equally well for other domains, depending on your
interests and audience. Maybe a "foodlog", a "catlog" or a "treklog" could also
work well.
The devlog section contains more information about how devlogs can be implemented
in Zine.
Some examples of devlogs in the wild:
- https://zine-ssg.io/log/
- https://ziglang.org/devlog/
## Next steps
Make sure to read the [official Zine docs](https://zine-ssg.io/docs/)
and then start editing this website!
Start by putting the correct information in `zine.ziggy` and then start editing
the existing pages. Before deleting existing copy consider giving it a brief
look as it will show you some SuperMD specific syntax.
HTML markup in Zine is defined via SuperHTML templates:
- `layouts/index.shtml`
- `layouts/page.shtml`
- `layouts/post.shtml`
- `layouts/blog.shtml`
- `layouts/blog.xml`
- `layouts/devlog.shtml`
- `layouts/devlog.xml`
- `layouts/devlog-archive.shtml`
- `layouts/templates/base.shtml`
**If you're running the Zine development server (by running `zine`), then all
changes you make will be picked up immediately, causing the website to rebuild
and the page in your browser to refresh**.
You can learn more about SuperMD and SuperHTML in [/about/](/about/).
Lastly, this sample website also includes the following asset files:
- `assets/style.css`
- `assets/hightlight.css`
- `assets/under-construction.gif`
- `assets/katex-tag.js`
- `assets/katex0.16.21.css`
- `assets/katex0.16.21.js`
- `content/blog/first-post/fanzine.jpg`
The first few asset files are **site assets**, while the last is a **page asset** that belongs to the "first post" page.
The Zine docs contain more information about [dealing with assets](https://zine-ssg.io/docs/assets/).
I'm always happy to chat, feel free to reach out to me a @yadunut on (Twitter, Instagram, Telegram) or on [email](mailto:blog@yadunut.com)

View File

@ -0,0 +1,16 @@
---
.title = "Microblog - 2025",
.date = @date("2025-01-01"),
.author = "Yadunand Prem",
.layout = "microblog.shtml",
.draft = false,
---
[]($section.id('about'))
## About
A place for short form thoughts and ideas
> This page lists entries for the current year, for past entries consult the [microblog archive](/microblog/).
## [Hello World]($section.id("2025-08-05"))
This is the first entry in this year's microblog created with [Zine](https://zine-ssg.io)! I'm exploring using Jujutsu as a VCS right now, and it seems interesting. The site data can be found [here](https://git.yadunut.dev/yadunut/yadunut.dev).

View File

@ -0,0 +1,14 @@
---
.title = "Microblog Archive",
.date = @date("2025-01-01"),
.author = "Yadunand Prem",
.layout = "microblog-archive.shtml",
.alternatives = [{
.name = "rss",
.layout = "microblog.xml",
.output = "index.xml",
}],
.draft = false,
---
The archive of my microblogging posts by year

View File

@ -4,7 +4,7 @@
.date {
font-size: 0.9em;
}
.title h3{
margin-top: 0;
}
@ -22,4 +22,4 @@
</a>
</div>
</div>
</body>
</body>

View File

@ -2,7 +2,7 @@
<channel>
<title :text="$site.title"></title>
<link :text="$site.host_url"></link>
<description :text="$site.title.suffix(' - Devlog')"></description>
<description :text="$site.title.suffix(' - Microblog')"></description>
<generator>Zine -- https://zine-ssg.io</generator>
<language>en-US</language>
<lastBuildDate :text="$build.generated.formatHTTP()"></lastBuildDate>

View File

@ -18,19 +18,15 @@
<nav>
<a href="$site.page('').link()">Home</a>
&nbsp; • &nbsp;
<a href="$site.page('about').link()">About</a>
&nbsp; • &nbsp;
<a href="$site.page('blog').link()">Blog</a>
<ctx :if="$site.page('devlog').subpages().first?()">
<ctx :if="$site.page('microblog').subpages().first?()">
&nbsp; • &nbsp;
<a href="$if.link()">Devlog</a>
<a href="$if.link()">Microblog</a>
</ctx>
</nav>
<super>
<footer>
<hr>
<h5>SITE UNDER CONSTRUCTION</h5>
<img src="$site.asset('under-construction.gif').link()" width=90>
</footer>
</body>
</html>
</html>

View File

@ -1,6 +1,6 @@
Site {
.title = "Welcome to Zine!",
.host_url = "https://example.com",
.title = "blog@yadunut",
.host_url = "https://yadunut.dev",
.content_dir_path = "content",
.layouts_dir_path = "layouts",
.assets_dir_path = "assets",