astro-deploy/src/pages/blog/[...slug].astro
Jewgeni Lewash 6c81e942a6 feat(blog): add additional frontmatter fields for dates, authors, image, draft
Add additional frontmatter fields and display the data on the blog page and the individual blogposts
2024-04-12 09:22:01 +02:00

100 lines
2.2 KiB
Plaintext

---
import { getCollection } from 'astro:content';
import type { CollectionEntry } from 'astro:content';
import BaseLayout from '@/layouts/BaseLayout.astro';
import Table from '@/components/blog/Table.astro';
import '@/styles/prose.css';
import { Image } from 'astro:assets';
export async function getStaticPaths() {
const blogEntries = await getCollection('blog');
return blogEntries
.filter((entry) => !entry.data.isDraft)
.map((entry) => ({
params: { slug: entry.slug },
props: { entry },
}));
}
interface Props {
entry: CollectionEntry<'blog'>;
}
const { entry } = Astro.props as Props;
const { Content } = await entry.render();
const components = { table: Table };
const {
title = '',
description = '',
author = [],
datePublished = '',
dateModified = '',
image = '',
} = entry.data;
const formatDate = (dateString: string) => {
const date = new Date(dateString);
return date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
};
const descriptionMeta =
description.length > 158 ? description.substring(0, 155) + '...' : description;
---
<BaseLayout title={title} description={descriptionMeta}>
<div
class="container prose mx-auto px-4 py-16 dark:prose-invert lg:px-8 lg:py-32 xl:max-w-7xl"
data-pagefind-body>
<h1 class="text-4xl font-bold">{title}</h1>
<div class="mt-2 text-sm text-gray-600">
{
author.length > 0 && (
<span>
By{' '}
{author.map((a, index) => (
<span>
{a.url ? (
<a href={a.url} target="_blank" rel="noopener noreferrer">
{a.name}
</a>
) : (
a.name
)}
{index < author.length - 1 ? ', ' : ''}
</span>
))}
</span>
)
}
{
datePublished && (
<span class="ml-2">Published on {formatDate(datePublished.toString())}</span>
)
}
{
dateModified && (
<span class="ml-2">Last updated on {formatDate(dateModified.toString())}</span>
)
}
</div>
{
image && (
<Image
src={image as unknown as string}
alt={title}
inferSize
class="mt-8 h-96 w-full rounded-lg object-cover"
/>
)
}
<div class="mt-8">
<Content components={components} />
</div>
</div>
</BaseLayout>