Create a reusable PostList component

This commit is contained in:
Maciej Pędzich 2023-05-13 03:43:13 +02:00
parent 9e5f1c6761
commit 9376546f3d
3 changed files with 82 additions and 25 deletions

View File

@ -0,0 +1,31 @@
---
import { CollectionEntry, getCollection } from 'astro:content';
export interface Props {
filterFn?: (entry: CollectionEntry<'blog'>) => unknown;
}
const defaultFilterFn = (entry: CollectionEntry<'blog'>) => true;
const { filterFn = defaultFilterFn } = Astro.props;
const posts = (
await getCollection(
'blog',
(entry) => filterFn(entry) && (import.meta.env.DEV || !entry.data.draft)
)
).sort((a, b) => a.data.pubDate.valueOf() - b.data.pubDate.valueOf());
---
<ul class="post-list">
{
posts.length === 0 ? (
<p>No posts were found</p>
) : (
posts.map((post) => (
<li>
<a href={`/blog/${post.slug}`}>{post.data.title}</a>
</li>
))
)
}
</ul>

View File

@ -6,21 +6,59 @@ import FormattedDate from '../components/FormattedDate.astro';
type Props = CollectionEntry<'blog'>['data']; type Props = CollectionEntry<'blog'>['data'];
const { title, description, pubDate } = Astro.props; const { title, description, pubDate, draft, tags, categories } = Astro.props;
const [category] = categories;
--- ---
<BaseLayout title={title} description={description}> <BaseLayout title={title} description={description}>
<article> <article>
<h1 class="title">{title}</h1> <h1 class="title">{title}</h1>
<FormattedDate date={pubDate} /> <div id="metadata">
<p>date published: <FormattedDate date={pubDate} /></p>
<p>
category:
<span>
<a href={`/blog/categories/${encodeURIComponent(category)}`}
>{category}</a
>
</span>
</p>
<p>
<span
set:html={'tags: ' +
tags
.map((tag) => `<a href="/blog/tags/${tag}">${tag}</a>`)
.join(', ')}
/>
{
draft && (
<div id="draft-warning">
<strong>
This is a draft! Its content is subject to change.
</strong>
</div>
)
}
</p>
<slot /> <slot />
</div>
</article> </article>
</BaseLayout>
<style> <style>
#metadata p {
margin-top: 0;
margin-bottom: 0.2rem;
}
.title { .title {
font-size: 2em; font-size: 2em;
margin: 0; margin: 0;
}
#metadata p,
#draft-warning,
.title {
text-align: center; text-align: center;
} }
</style> </style>
</BaseLayout>

View File

@ -1,10 +1,6 @@
--- ---
import { getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import PostList from '../../components/PostList.astro';
const posts = (await getCollection('blog', (entry) => !entry.data.draft)).sort(
(a, b) => a.data.pubDate.valueOf() - b.data.pubDate.valueOf()
);
--- ---
<BaseLayout <BaseLayout
@ -13,15 +9,7 @@ const posts = (await getCollection('blog', (entry) => !entry.data.draft)).sort(
> >
<section> <section>
<h2>My blog</h2> <h2>My blog</h2>
<ul class="post-list"> <PostList />
{
posts.map((post) => (
<li>
<a href={`/blog/${post.slug}/`}>{post.data.title}</a>
</li>
))
}
</ul>
</section> </section>
</BaseLayout> </BaseLayout>