From 321c4c6f04233d251c7544646cd1f64abb9637e7 Mon Sep 17 00:00:00 2001 From: Latte Date: Sat, 7 Mar 2026 18:39:41 +0100 Subject: [PATCH] Add Links page, collection, and nav entry --- src/components/Nav.astro | 1 + src/content/config.ts | 14 +- src/content/links/32bit-cafe.md | 8 + src/content/links/indieweb.md | 8 + src/content/links/low-tech-magazine.md | 8 + src/content/links/privacy-guides.md | 8 + src/content/links/the-marginalian.md | 8 + src/pages/links.astro | 370 +++++++++++++++++++++++++ 8 files changed, 424 insertions(+), 1 deletion(-) create mode 100644 src/content/links/32bit-cafe.md create mode 100644 src/content/links/indieweb.md create mode 100644 src/content/links/low-tech-magazine.md create mode 100644 src/content/links/privacy-guides.md create mode 100644 src/content/links/the-marginalian.md create mode 100644 src/pages/links.astro diff --git a/src/components/Nav.astro b/src/components/Nav.astro index 4110861..54efdfd 100644 --- a/src/components/Nav.astro +++ b/src/components/Nav.astro @@ -12,6 +12,7 @@ const links = [ { href: "/blog", label: "blog" }, { href: "/coffee", label: "coffee" }, { href: "/library", label: "library" }, + { href: "/links", label: "links" }, { href: "/ai", label: "ai" }, { href: "/changelog", label: "changelog" }, ]; diff --git a/src/content/config.ts b/src/content/config.ts index 9db50cc..576e52f 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -29,4 +29,16 @@ const coffee = defineCollection({ }), }); -export const collections = { blog, coffee }; +const links = defineCollection({ + type: "content", + schema: z.object({ + title: z.string(), + url: z.string().url(), + description: z.string(), + category: z.string().optional(), + date: z.coerce.date().optional(), + draft: z.boolean().optional().default(false), + }), +}); + +export const collections = { blog, coffee, links }; diff --git a/src/content/links/32bit-cafe.md b/src/content/links/32bit-cafe.md new file mode 100644 index 0000000..e3f5682 --- /dev/null +++ b/src/content/links/32bit-cafe.md @@ -0,0 +1,8 @@ +--- +title: "32-Bit Cafe" +url: "https://32bit.cafe" +description: "A warm small-web corner full of personal pages, guides, and gentle encouragement to make something of your own on the internet." +category: "inspiration" +date: 2026-03-06 +draft: false +--- diff --git a/src/content/links/indieweb.md b/src/content/links/indieweb.md new file mode 100644 index 0000000..fdfa7a6 --- /dev/null +++ b/src/content/links/indieweb.md @@ -0,0 +1,8 @@ +--- +title: "IndieWeb" +url: "https://indieweb.org" +description: "A lot of the values behind Hidden Den rhyme with this community: personal sites, ownership, and a web made of real places instead of only platforms." +category: "blogs" +date: 2026-03-07 +draft: false +--- diff --git a/src/content/links/low-tech-magazine.md b/src/content/links/low-tech-magazine.md new file mode 100644 index 0000000..d9814ea --- /dev/null +++ b/src/content/links/low-tech-magazine.md @@ -0,0 +1,8 @@ +--- +title: "Low-tech Magazine" +url: "https://solar.lowtechmagazine.com" +description: "Thoughtful writing about technology, infrastructure, energy, and limits. It is one of those rare places that feels both technical and deeply reflective." +category: "essays" +date: 2026-03-04 +draft: false +--- diff --git a/src/content/links/privacy-guides.md b/src/content/links/privacy-guides.md new file mode 100644 index 0000000..de97b6b --- /dev/null +++ b/src/content/links/privacy-guides.md @@ -0,0 +1,8 @@ +--- +title: "Privacy Guides" +url: "https://www.privacyguides.org" +description: "One of the more practical places for thinking about privacy tools without drifting too far into paranoia or purity spirals." +category: "tools" +date: 2026-03-05 +draft: false +--- diff --git a/src/content/links/the-marginalian.md b/src/content/links/the-marginalian.md new file mode 100644 index 0000000..bf7bfc6 --- /dev/null +++ b/src/content/links/the-marginalian.md @@ -0,0 +1,8 @@ +--- +title: "The Marginalian" +url: "https://www.themarginalian.org" +description: "A long-running archive of essays, ideas, and literary wandering. Good when I want to remember that thoughtful writing can still feel generous and alive." +category: "essays" +date: 2026-03-03 +draft: false +--- diff --git a/src/pages/links.astro b/src/pages/links.astro new file mode 100644 index 0000000..946aa48 --- /dev/null +++ b/src/pages/links.astro @@ -0,0 +1,370 @@ +--- +import BaseLayout from "../layouts/BaseLayout.astro"; +import { getCollection } from "astro:content"; + +const links = (await getCollection("links", ({ data }) => !data.draft)).map( + (entry) => ({ + ...entry, + host: new URL(entry.data.url).hostname.replace(/^www\./, ""), + }), +); + +const categoryOrder = [ + "blogs", + "essays", + "tools", + "inspiration", + "music", + "infrastructure", +]; + +const compareLinks = (a: (typeof links)[number], b: (typeof links)[number]) => { + if (a.data.date && b.data.date) { + return b.data.date.valueOf() - a.data.date.valueOf(); + } + + if (a.data.date) return -1; + if (b.data.date) return 1; + + return a.data.title.localeCompare(b.data.title); +}; + +const groupedLinks = Array.from( + links.reduce((groups, link) => { + const category = link.data.category ?? "uncategorized"; + const current = groups.get(category) ?? []; + + current.push(link); + groups.set(category, current); + return groups; + }, new Map()), +).sort(([a], [b]) => { + const leftIndex = categoryOrder.indexOf(a); + const rightIndex = categoryOrder.indexOf(b); + const normalizedLeft = + leftIndex === -1 ? Number.MAX_SAFE_INTEGER : leftIndex; + const normalizedRight = + rightIndex === -1 ? Number.MAX_SAFE_INTEGER : rightIndex; + + if (normalizedLeft !== normalizedRight) { + return normalizedLeft - normalizedRight; + } + + return a.localeCompare(b); +}); + +for (const [, entries] of groupedLinks) { + entries.sort(compareLinks); +} + +function formatCategory(category: string) { + if (category === "uncategorized") return "Elsewhere"; + return category.replace(/\b\w/g, (char) => char.toUpperCase()); +} + +function formatDate(date?: Date) { + if (!date) return null; + return date.toISOString().split("T")[0]; +} +--- + + + + +
+
+
+

A wider web

+

Links

+
==============================
+

+ This is a small cabinet of links that matter to me: tools, + essays, communities, and other corners of the web that have + influenced how I think about building places online. Not a + giant bookmark dump, just a shelf of things worth sharing. +

+
+ +
+ { + groupedLinks.map(([category, entries]) => ( +
+

+ {formatCategory(category)} +

+ +
+ )) + } +
+ +
+

Made with love by Latte

+
+
+
+
+ + -- 2.52.0