From bd0dc30f9e1aa55d3f6ea958ced5799c65a86354 Mon Sep 17 00:00:00 2001 From: Latte Date: Sat, 7 Mar 2026 18:07:23 +0100 Subject: [PATCH] Add curated essays and reading paths Introduce a Library page and wire it into the main nav. Add blog frontmatter fields: category, featuredEssay (default false), and readingOrder (positive integer). Update several posts to mark featured essays and assign readingOrder for the recommended path. --- src/components/Nav.astro | 1 + src/content/blog/after-the-silence.md | 2 + ...-building-quiet-corners-on-the-internet.md | 3 + src/content/blog/hello-world.md | 3 + .../things-i-learned-from-loving-deeply.md | 3 + src/content/config.ts | 3 + src/pages/library.astro | 610 ++++++++++++++++++ 7 files changed, 625 insertions(+) create mode 100644 src/pages/library.astro diff --git a/src/components/Nav.astro b/src/components/Nav.astro index b1dcfeb..4110861 100644 --- a/src/components/Nav.astro +++ b/src/components/Nav.astro @@ -11,6 +11,7 @@ const links = [ { href: "/uses", label: "uses" }, { href: "/blog", label: "blog" }, { href: "/coffee", label: "coffee" }, + { href: "/library", label: "library" }, { href: "/ai", label: "ai" }, { href: "/changelog", label: "changelog" }, ]; diff --git a/src/content/blog/after-the-silence.md b/src/content/blog/after-the-silence.md index 4cd7bb8..c335daa 100644 --- a/src/content/blog/after-the-silence.md +++ b/src/content/blog/after-the-silence.md @@ -3,6 +3,8 @@ title: "After the Silence" description: "Reflections on what remains after a meaningful relationship ends, and how love can transform without disappearing." pubDate: 2026-03-04 tags: ["love", "reflection", "healing", "relationships", "personal"] +category: "reflection" +featuredEssay: true --- When a relationship ends, the world does not become quiet immediately. diff --git a/src/content/blog/coffee-and-code-1-building-quiet-corners-on-the-internet.md b/src/content/blog/coffee-and-code-1-building-quiet-corners-on-the-internet.md index df60f97..55be7f0 100644 --- a/src/content/blog/coffee-and-code-1-building-quiet-corners-on-the-internet.md +++ b/src/content/blog/coffee-and-code-1-building-quiet-corners-on-the-internet.md @@ -3,6 +3,9 @@ title: "Coffee & Code #1 - Building Quiet Corners on the Internet" description: "Why personal websites still matter, and why I want Hidden Den to feel more like a quiet cafe than another loud platform." pubDate: 2026-03-07 tags: ["coffee-and-code", "internet", "technology", "philosophy", "devlog", "personal website"] +category: "internet" +featuredEssay: true +readingOrder: 2 series: name: "Coffee & Code" part: 1 diff --git a/src/content/blog/hello-world.md b/src/content/blog/hello-world.md index 1cf92c2..680801e 100644 --- a/src/content/blog/hello-world.md +++ b/src/content/blog/hello-world.md @@ -3,6 +3,9 @@ title: "Welcome to the Den" description: "First proper post. Why I built this site, what it runs on, and what to expect." pubDate: 2026-03-01 tags: ["self-hosting", "privacy", "personal-web", "infrastructure"] +category: "building" +featuredEssay: true +readingOrder: 1 draft: false --- diff --git a/src/content/blog/things-i-learned-from-loving-deeply.md b/src/content/blog/things-i-learned-from-loving-deeply.md index e97bd3e..b2db983 100644 --- a/src/content/blog/things-i-learned-from-loving-deeply.md +++ b/src/content/blog/things-i-learned-from-loving-deeply.md @@ -3,6 +3,9 @@ title: "Things I Learned From Loving Deeply" description: "Reflections on intimacy, trust, and the quiet ways meaningful love can continue shaping who we become." pubDate: 2026-03-07 tags: ["love", "relationships", "reflection", "emotional growth", "intimacy"] +category: "personal" +featuredEssay: true +readingOrder: 3 --- Some relationships change you in quiet but permanent ways. diff --git a/src/content/config.ts b/src/content/config.ts index e86ca9b..9db50cc 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -7,6 +7,9 @@ const blog = defineCollection({ description: z.string(), pubDate: z.coerce.date(), tags: z.array(z.string()).default([]), + category: z.string().optional(), + featuredEssay: z.boolean().optional().default(false), + readingOrder: z.number().int().positive().optional(), series: z .object({ name: z.string(), diff --git a/src/pages/library.astro b/src/pages/library.astro new file mode 100644 index 0000000..24c5c13 --- /dev/null +++ b/src/pages/library.astro @@ -0,0 +1,610 @@ +--- +import BaseLayout from "../layouts/BaseLayout.astro"; +import { getCollection } from "astro:content"; +import { formatBlogDate } from "../lib/blog"; +import { getReadingTime } from "../lib/readingTime"; + +const featuredEssays = ( + await getCollection("blog", ({ data }) => !data.draft && data.featuredEssay) +).sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()); + +const curatedEssays = featuredEssays.map((post) => ({ + ...post, + readingTime: getReadingTime(post.body), +})); + +const recommendedPath = curatedEssays + .filter((post) => typeof post.data.readingOrder === "number") + .sort( + (a, b) => + (a.data.readingOrder ?? Number.MAX_SAFE_INTEGER) - + (b.data.readingOrder ?? Number.MAX_SAFE_INTEGER), + ); + +const categoryMap = new Map(); + +for (const post of curatedEssays) { + if (!post.data.category) continue; + + const current = categoryMap.get(post.data.category) ?? []; + current.push(post); + categoryMap.set(post.data.category, current); +} + +const categoryGroups = [...categoryMap.entries()].sort(([a], [b]) => + a.localeCompare(b), +); + +function formatCategory(category: string) { + return category.replace(/\b\w/g, (char) => char.toUpperCase()); +} +--- + + + + +
+
+
+

Deeper writing

+

Library

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

+ This is the quieter shelf of the den: a place for longer + posts, reflective essays, and writing worth revisiting. The + blog keeps the full archive. The library is a smaller, + curated reading room. +

+
+ + { + curatedEssays.length === 0 ? ( +
+
+

+ The shelf is still being arranged. For now, the + deeper writing still lives in the blog until + more posts are marked for the library. +

+
+
+ ) : ( + <> +
+
+

+ Highlighted Essays +

+ + Browse all posts + +
+

+ A small curated shelf of the more substantial + writing on the site. +

+
    + {curatedEssays.map((post) => ( +
  • +
    +
    +
    + + + + {post.readingTime.text} + +
    + {post.data.category && ( + + {formatCategory( + post.data.category, + )} + + )} +
    +

    + + {post.data.title} + +

    +

    {post.data.description}

    + + Read essay + +
    +
  • + ))} +
+
+ + {recommendedPath.length >= 2 && ( +
+

+ Recommended Reading Path +

+

+ If you want a gentle path through the longer + writing, start here. +

+
    + {recommendedPath.map((post) => ( +
  1. + + {post.data.readingOrder} + +
    +

    + + {post.data.title} + +

    +

    {post.data.description}

    +
    + + {formatBlogDate( + post.data.pubDate, + )} + + + + {post.readingTime.text} + +
    +
    +
  2. + ))} +
+
+ )} + + {categoryGroups.length > 0 && ( +
+

Browse By Theme

+

+ The same shelf, grouped more loosely by what + each piece leans toward. +

+
+ {categoryGroups.map(([category, posts]) => ( +
+

+ {formatCategory(category)} +

+
    + {posts.map((post) => ( +
  • + + {post.data.title} + + + {formatBlogDate( + post.data + .pubDate, + )}{" "} + ·{" "} + { + post.readingTime + .text + } + +
  • + ))} +
+
+ ))} +
+
+ )} + + ) + } + +
+

Made with love by Latte

+
+
+
+
+ + -- 2.52.0