feat: related field
This commit is contained in:
parent
23d34ae3ab
commit
c10ebb3c1d
4 changed files with 33 additions and 8 deletions
|
|
@ -11,6 +11,7 @@ const md = defineCollection({
|
||||||
pinned: z.boolean().optional(),
|
pinned: z.boolean().optional(),
|
||||||
category: z.string().optional(),
|
category: z.string().optional(),
|
||||||
draft: z.boolean().optional(),
|
draft: z.boolean().optional(),
|
||||||
|
related: z.array(z.string()).optional(),
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,14 @@ function sortPosts(posts: PostWithDates[]): PostWithDates[] {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resolveRelatedPosts(
|
||||||
|
slugs: string[],
|
||||||
|
allPosts: PostWithDates[],
|
||||||
|
): PostWithDates[] {
|
||||||
|
const bySlug = new Map(allPosts.map(p => [getSlug(p.id), p]));
|
||||||
|
return slugs.flatMap(s => bySlug.get(s) ?? []);
|
||||||
|
}
|
||||||
|
|
||||||
export function organizePostsByCategory(posts: PostWithDates[]): {
|
export function organizePostsByCategory(posts: PostWithDates[]): {
|
||||||
grouped: Record<string, PostWithDates[]>;
|
grouped: Record<string, PostWithDates[]>;
|
||||||
categories: string[];
|
categories: string[];
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ export const prerender = false;
|
||||||
import { getCollection, render } from 'astro:content';
|
import { getCollection, render } from 'astro:content';
|
||||||
import { requireAdminSession } from '../../lib/auth';
|
import { requireAdminSession } from '../../lib/auth';
|
||||||
import Layout from '../../layouts/Layout.astro';
|
import Layout from '../../layouts/Layout.astro';
|
||||||
import { formatDate } from '../../lib/format';
|
import { formatDate, formatListItem } from '../../lib/format';
|
||||||
import { getSlug, enrichPostWithDates } from '../../lib/md';
|
import { getSlug, enrichPostWithDates, enrichPostsWithDates, resolveRelatedPosts } from '../../lib/md';
|
||||||
|
|
||||||
const { session, error } = await requireAdminSession(Astro.request);
|
const { session, error } = await requireAdminSession(Astro.request);
|
||||||
if (error) return error;
|
if (error) return error;
|
||||||
|
|
@ -19,8 +19,10 @@ if (!rawPost) {
|
||||||
return new Response('Not found', { status: 404 });
|
return new Response('Not found', { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const allPosts = enrichPostsWithDates(rawPosts);
|
||||||
const post = enrichPostWithDates(rawPost);
|
const post = enrichPostWithDates(rawPost);
|
||||||
const { Content } = await render(post);
|
const { Content } = await render(post);
|
||||||
|
const related = post.data.related ? resolveRelatedPosts(post.data.related, allPosts) : [];
|
||||||
---
|
---
|
||||||
<Layout title={`${post.data.title} - lewis m.w.`}>
|
<Layout title={`${post.data.title} - lewis m.w.`}>
|
||||||
|
|
||||||
|
|
@ -29,4 +31,10 @@ const { Content } = await render(post);
|
||||||
<p class="muted" style="margin-top: 0;">{formatDate(post.dates.created)}{post.dates.updated && ` (updated ${formatDate(post.dates.updated)})`}</p>
|
<p class="muted" style="margin-top: 0;">{formatDate(post.dates.created)}{post.dates.updated && ` (updated ${formatDate(post.dates.updated)})`}</p>
|
||||||
<Content />
|
<Content />
|
||||||
</article>
|
</article>
|
||||||
|
{related.length > 0 && (
|
||||||
|
<details open>
|
||||||
|
<summary>related</summary>
|
||||||
|
<pre set:html={related.map(p => formatListItem(p.dates.created, `/draft/${getSlug(p.id)}`, p.data.title)).join('\n')} />
|
||||||
|
</details>
|
||||||
|
)}
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,21 @@
|
||||||
---
|
---
|
||||||
import { getCollection, render } from 'astro:content';
|
import { getCollection, render } from 'astro:content';
|
||||||
import Layout from '../../layouts/Layout.astro';
|
import Layout from '../../layouts/Layout.astro';
|
||||||
import { formatDate } from '../../lib/format';
|
import { formatDate, formatListItem } from '../../lib/format';
|
||||||
import { getSlug, enrichPostWithDates } from '../../lib/md';
|
import { getSlug, enrichPostWithDates, enrichPostsWithDates, resolveRelatedPosts } from '../../lib/md';
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const posts = await getCollection('md', ({ data }) => data.draft !== true);
|
const rawPosts = await getCollection('md', ({ data }) => data.draft !== true);
|
||||||
return posts.map(post => ({
|
const allPosts = enrichPostsWithDates(rawPosts);
|
||||||
|
return allPosts.map(post => ({
|
||||||
params: { slug: getSlug(post.id) },
|
params: { slug: getSlug(post.id) },
|
||||||
props: { post: enrichPostWithDates(post) }
|
props: { post, allPosts }
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { post } = Astro.props;
|
const { post, allPosts } = Astro.props;
|
||||||
const { Content } = await render(post);
|
const { Content } = await render(post);
|
||||||
|
const related = post.data.related ? resolveRelatedPosts(post.data.related, allPosts) : [];
|
||||||
---
|
---
|
||||||
<Layout title={`${post.data.title} - lewis m.w.`}>
|
<Layout title={`${post.data.title} - lewis m.w.`}>
|
||||||
|
|
||||||
|
|
@ -22,4 +24,10 @@ const { Content } = await render(post);
|
||||||
<p class="muted" style="margin-top: 0;">{formatDate(post.dates.created)}{post.dates.updated && ` (updated ${formatDate(post.dates.updated)})`}</p>
|
<p class="muted" style="margin-top: 0;">{formatDate(post.dates.created)}{post.dates.updated && ` (updated ${formatDate(post.dates.updated)})`}</p>
|
||||||
<Content />
|
<Content />
|
||||||
</article>
|
</article>
|
||||||
|
{related.length > 0 && (
|
||||||
|
<details open>
|
||||||
|
<summary>related</summary>
|
||||||
|
<pre set:html={related.map(p => formatListItem(p.dates.created, `/md/${getSlug(p.id)}`, p.data.title)).join('\n')} />
|
||||||
|
</details>
|
||||||
|
)}
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue