mirror of
https://github.com/andwati/andwati.com.git
synced 2026-11-06 09:32:19 +00:00
Wire Astro content collections to the shared content/ directory
Adds a custom Astro loader that reads the Zola-style TOML frontmatter (+++ ... +++) directly, so content/ stays the single source of truth with no YAML conversion step. Defines writings/portfolio/bookshelf/ blogs collections and basic list/detail pages for each, rendering the seed entries end-to-end (verified in-browser via `pnpm --filter site dev`). This is the first runnable MVP: home, writings list + post detail, portfolio, bookshelf (books and papers), and curated blogs all render from real content/ files.
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
---
|
||||
import { getCollection, render } from "astro:content";
|
||||
import Base from "../../layouts/Base.astro";
|
||||
|
||||
const blogs = await getCollection("blogs");
|
||||
const rendered = await Promise.all(
|
||||
blogs.map(async (entry) => ({
|
||||
entry,
|
||||
Content: (await render(entry)).Content,
|
||||
})),
|
||||
);
|
||||
---
|
||||
|
||||
<Base title="Blogs I follow">
|
||||
<h1>Blogs I follow</h1>
|
||||
{
|
||||
rendered.map(({ entry, Content }) => (
|
||||
<div class="card">
|
||||
<h3>
|
||||
<a href={entry.data.url}>{entry.data.title}</a>
|
||||
</h3>
|
||||
<Content />
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</Base>
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import Base from "../../layouts/Base.astro";
|
||||
|
||||
const items = (await getCollection("bookshelf")).sort(
|
||||
(a, b) =>
|
||||
(b.data.date_finished?.valueOf() ?? 0) -
|
||||
(a.data.date_finished?.valueOf() ?? 0),
|
||||
);
|
||||
---
|
||||
|
||||
<Base title="Bookshelf">
|
||||
<h1>Bookshelf</h1>
|
||||
{
|
||||
items.map((entry) => (
|
||||
<div class="card">
|
||||
<h3>
|
||||
{entry.data.title} <span class="tag">{entry.data.kind}</span>
|
||||
</h3>
|
||||
<p class="meta">{entry.data.authors.join(", ")}</p>
|
||||
{entry.data.rating && <p class="meta">{"★".repeat(entry.data.rating)}</p>}
|
||||
{entry.data.status && <p class="meta">{entry.data.status}</p>}
|
||||
{entry.data.kind === "book" && entry.data.isbn && <p class="meta">ISBN {entry.data.isbn}</p>}
|
||||
{entry.data.kind === "paper" && entry.data.arxiv_id && (
|
||||
<p class="meta">
|
||||
arXiv:{entry.data.arxiv_id}
|
||||
{entry.data.url && (
|
||||
<>
|
||||
{" "}
|
||||
· <a href={entry.data.url}>source</a>
|
||||
</>
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</Base>
|
||||
@@ -1,17 +1,28 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import Base from "../layouts/Base.astro";
|
||||
|
||||
const writings = (await getCollection("writings", ({ data }) => !data.draft))
|
||||
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
|
||||
.slice(0, 3);
|
||||
---
|
||||
|
||||
---
|
||||
<Base title="Home">
|
||||
<h1>Ian Andwati</h1>
|
||||
<p>Computer science, mathematics, life, and beliefs.</p>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>Astro</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Astro</h1>
|
||||
</body>
|
||||
</html>
|
||||
<h2>Latest writings</h2>
|
||||
{
|
||||
writings.length === 0 ? (
|
||||
<p class="meta">No writings published yet.</p>
|
||||
) : (
|
||||
writings.map((entry) => (
|
||||
<div class="card">
|
||||
<h3><a href={`/writings/${entry.id}/`}>{entry.data.title}</a></h3>
|
||||
<p class="meta">{entry.data.date.toDateString()}</p>
|
||||
{entry.data.description && <p>{entry.data.description}</p>}
|
||||
</div>
|
||||
))
|
||||
)
|
||||
}
|
||||
</Base>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import Base from "../../layouts/Base.astro";
|
||||
|
||||
const projects = (
|
||||
await getCollection("portfolio", ({ data }) => !data.draft)
|
||||
).sort(
|
||||
(a, b) =>
|
||||
(b.data.date_start?.valueOf() ?? 0) - (a.data.date_start?.valueOf() ?? 0),
|
||||
);
|
||||
---
|
||||
|
||||
<Base title="Portfolio">
|
||||
<h1>Portfolio</h1>
|
||||
{
|
||||
projects.map((entry) => (
|
||||
<div class="card">
|
||||
<h3>{entry.data.title}</h3>
|
||||
<p class="meta">{entry.data.role}</p>
|
||||
{entry.data.description && <p>{entry.data.description}</p>}
|
||||
{entry.data.outcome && <p>{entry.data.outcome}</p>}
|
||||
{entry.data.links.map((link) => (
|
||||
<a href={link.url}>{link.label}</a>
|
||||
))}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</Base>
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
import { getCollection, render } from "astro:content";
|
||||
import Base from "../../layouts/Base.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const writings = await getCollection("writings", ({ data }) => !data.draft);
|
||||
return writings.map((entry) => ({
|
||||
params: { slug: entry.id },
|
||||
props: { entry },
|
||||
}));
|
||||
}
|
||||
|
||||
const { entry } = Astro.props;
|
||||
const { Content } = await render(entry);
|
||||
---
|
||||
|
||||
<Base title={entry.data.title}>
|
||||
<h1>{entry.data.title}</h1>
|
||||
<p class="meta">
|
||||
{entry.data.date.toDateString()}
|
||||
{entry.data.updated && <> · updated {entry.data.updated.toDateString()}</>}
|
||||
</p>
|
||||
{entry.data.taxonomies?.tags.map((tag) => <span class="tag">#{tag}</span>)}
|
||||
<article>
|
||||
<Content />
|
||||
</article>
|
||||
</Base>
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import Base from "../../layouts/Base.astro";
|
||||
|
||||
const writings = (
|
||||
await getCollection("writings", ({ data }) => !data.draft)
|
||||
).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
|
||||
---
|
||||
|
||||
<Base title="Writings">
|
||||
<h1>Writings</h1>
|
||||
{
|
||||
writings.map((entry) => (
|
||||
<div class="card">
|
||||
<h3><a href={`/writings/${entry.id}/`}>{entry.data.title}</a></h3>
|
||||
<p class="meta">{entry.data.date.toDateString()}</p>
|
||||
{entry.data.description && <p>{entry.data.description}</p>}
|
||||
{entry.data.taxonomies?.tags.map((tag) => <span class="tag">#{tag}</span>)}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</Base>
|
||||
Reference in New Issue
Block a user