--- import BaseLayout from "~/layouts/BaseLayout.astro"; import Eyebrow from "~/components/atoms/Eyebrow.astro"; import Mark from "~/components/atoms/Mark.astro"; import PostRow from "~/components/molecules/PostRow.astro"; import YearHead from "~/components/molecules/YearHead.astro"; import InkArrow from "~/components/atoms/InkArrow.astro"; import BlogSearch from "~/components/molecules/BlogSearch.astro"; import { blog } from "~/lib/urls"; import { getCollection } from "astro:content"; const posts = await getCollection("posts", ({ data }) => !data.draft); posts.sort((a, b) => b.data.date.getTime() - a.data.date.getTime()); const [featured, ...rest] = posts; const dateFmtMonthYear = new Intl.DateTimeFormat("en-AU", { month: "short", year: "numeric" }); const dateFmtMonthYearLong = new Intl.DateTimeFormat("en-AU", { month: "long", year: "numeric" }); // Group the archive by year. const byYear = new Map(); for (const post of rest) { const year = post.data.date.getFullYear(); const bucket = byYear.get(year) ?? []; bucket.push(post); byYear.set(year, bucket); } const yearGroups = Array.from(byYear.entries()).sort(([a], [b]) => b - a); // Build the per-post `data-search` string at build time. We concatenate the // searchable fields, lowercase, strip a small set of markdown punctuation, and // collapse whitespace. Body text is the raw markdown from the content // collection entry's `.body` property — MDX expressions that survive end up as // literal text, which is harmless for substring matching. function buildSearchText(post: (typeof posts)[number]): string { const parts = [ post.data.title, post.data.tag, post.data.standfirst, post.data.description, post.body ?? "", ].filter(Boolean) as string[]; return parts .join(" ") .toLowerCase() .replace(/[<>#*_`\[\]()]/g, " ") .replace(/\s+/g, " ") .trim(); } const searchTextById = new Map(); for (const post of posts) { searchTextById.set(post.id, buildSearchText(post)); } ---
Journal · field notes

Writing.

{posts.length} entries · since 2021

Short pieces on craft, the ocean, and the quiet discipline of making small software. Mostly written early, before the light is up.

{ featured && (
{featured.data.tag && {featured.data.tag}} {dateFmtMonthYearLong.format(featured.data.date)} {featured.data.readingMinutes && ` · ${featured.data.readingMinutes} min`}

{featured.data.title}

{featured.data.standfirst &&

{featured.data.standfirst}

} Read the piece
) }
{ yearGroups.map(([year, items]) => ( <> {items.map((post) => ( ))} )) }