Update post collection and show category on posts

This commit is contained in:
prototypa
2023-01-24 01:26:37 -05:00
parent c9c555e0ef
commit 64bcda934c
12 changed files with 42 additions and 16 deletions

View File

@ -3,9 +3,7 @@ const { title = await Astro.slots.render('default'), subtitle = await Astro.slot
--- ---
<header class="mb-8 md:mb-16 text-center max-w-3xl mx-auto"> <header class="mb-8 md:mb-16 text-center max-w-3xl mx-auto">
<h1 class="text-4xl md:text-5xl font-bold leading-tighter tracking-tighter font-heading"> <h1 class="text-4xl md:text-5xl font-bold leading-tighter tracking-tighter font-heading" set:html={title} />
{title}
</h1>
{ {
subtitle && ( subtitle && (
<div class="mt-2 md:mt-3 mx-auto text-xl text-gray-500 dark:text-slate-400 font-medium" set:html={subtitle} /> <div class="mt-2 md:mt-3 mx-auto text-xl text-gray-500 dark:text-slate-400 font-medium" set:html={subtitle} />

View File

@ -43,8 +43,19 @@ const link = !BLOG?.post?.disabled ? getPermalink(post.permalink, 'post') : '';
<header> <header>
<div class="mb-1"> <div class="mb-1">
<span class="text-sm"> <span class="text-sm">
<Icon name="tabler:clock" class="w-3.5 h-3.5 inline-block -mt-0.5 dark:text-gray-400" /> <Icon name="tabler:clock" class="w-3.5 h-3.5 inline-block -mt-0.5 dark:text-gray-400" />
<time datetime={String(post.publishDate)}>{getFormattedDate(post.publishDate)}</time> <time datetime={String(post.publishDate)}>{getFormattedDate(post.publishDate)}</time>
{
post.category && (
<>
{' '} ·
<a class="capitalize hover:underline" href={getPermalink(post.category, 'category')}>
{post.category.replaceAll('-', ' ')}
</a>
</>
)
}
</span> </span>
</div> </div>
<h2 class="text-xl sm:text-2xl font-bold leading-tight mb-2 font-heading dark:text-slate-300"> <h2 class="text-xl sm:text-2xl font-bold leading-tight mb-2 font-heading dark:text-slate-300">

View File

@ -5,6 +5,7 @@ import { Picture } from '@astrojs/image/components';
import PostTags from '~/components/blog/Tags.astro'; import PostTags from '~/components/blog/Tags.astro';
import SocialShare from '~/components/common/SocialShare.astro'; import SocialShare from '~/components/common/SocialShare.astro';
import { getPermalink } from '~/utils/permalinks';
import { getFormattedDate } from '~/utils/utils'; import { getFormattedDate } from '~/utils/utils';
import type { Post } from '~/types'; import type { Post } from '~/types';
@ -22,8 +23,19 @@ const { post, url } = Astro.props;
<header class={post.image ? '' : ''}> <header class={post.image ? '' : ''}>
<div class="flex justify-between flex-col sm:flex-row max-w-3xl mx-auto mt-0 mb-2 px-4 sm:px-6 sm:items-center"> <div class="flex justify-between flex-col sm:flex-row max-w-3xl mx-auto mt-0 mb-2 px-4 sm:px-6 sm:items-center">
<p> <p>
<Icon name="tabler:clock" class="w-4 h-4 inline-block -mt-1 dark:text-gray-400" /> <Icon name="tabler:clock" class="w-4 h-4 inline-block -mt-0.5 dark:text-gray-400" />
<time datetime={String(post.publishDate)}>{getFormattedDate(post.publishDate)}</time> <time datetime={String(post.publishDate)}>{getFormattedDate(post.publishDate)}</time>
{
post.category && (
<>
{' '}
·
<a class="font-bold capitalize" href={getPermalink(post.category, 'category')}>
{post.category.replaceAll('-', ' ')}
</a>
</>
)
}
</p> </p>
</div> </div>
<h1 <h1

View File

@ -1,6 +1,6 @@
import { z, defineCollection } from 'astro:content'; import { z, defineCollection } from 'astro:content';
const posts = defineCollection({ const post = defineCollection({
schema: z.object({ schema: z.object({
title: z.string(), title: z.string(),
description: z.string().optional(), description: z.string().optional(),
@ -19,5 +19,5 @@ const posts = defineCollection({
}); });
export const collections = { export const collections = {
posts: posts, post: post,
}; };

View File

@ -42,7 +42,7 @@ const meta = {
<Layout meta={meta}> <Layout meta={meta}>
<section class="px-6 sm:px-6 py-12 sm:py-16 lg:py-20 mx-auto max-w-3xl"> <section class="px-6 sm:px-6 py-12 sm:py-16 lg:py-20 mx-auto max-w-3xl">
<Headline>Category {category}</Headline> <Headline><span class="capitalize">{category.replaceAll('-', ' ')}</span></Headline>
<BlogList posts={page.data} /> <BlogList posts={page.data} />
<Pagination prevUrl={page.url.prev} nextUrl={page.url.next} /> <Pagination prevUrl={page.url.prev} nextUrl={page.url.next} />
</section> </section>

View File

@ -1,7 +1,7 @@
import { getCollection } from 'astro:content'; import { getCollection } from 'astro:content';
import type { CollectionEntry } from 'astro:content'; import type { CollectionEntry } from 'astro:content';
import type { Post } from '~/types'; import type { Post } from '~/types';
import { cleanSlug, POST_PERMALINK_PATTERN } from './permalinks'; import { cleanSlug, trimSlash, POST_PERMALINK_PATTERN } from './permalinks';
const generatePermalink = async ({ id, slug, publishDate, category }) => { const generatePermalink = async ({ id, slug, publishDate, category }) => {
const year = String(publishDate.getFullYear()).padStart(4, '0'); const year = String(publishDate.getFullYear()).padStart(4, '0');
@ -11,25 +11,30 @@ const generatePermalink = async ({ id, slug, publishDate, category }) => {
const minute = String(publishDate.getMinutes()).padStart(2, '0'); const minute = String(publishDate.getMinutes()).padStart(2, '0');
const second = String(publishDate.getSeconds()).padStart(2, '0'); const second = String(publishDate.getSeconds()).padStart(2, '0');
return POST_PERMALINK_PATTERN const permalink = POST_PERMALINK_PATTERN.replace('%slug%', slug)
.replace('%slug%', slug)
.replace('%id%', id) .replace('%id%', id)
.replace('%category%', category) .replace('%category%', category || '')
.replace('%year%', year) .replace('%year%', year)
.replace('%month%', month) .replace('%month%', month)
.replace('%day%', day) .replace('%day%', day)
.replace('%hour%', hour) .replace('%hour%', hour)
.replace('%minute%', minute) .replace('%minute%', minute)
.replace('%second%', second); .replace('%second%', second);
return permalink
.split('/')
.map((el) => trimSlash(el))
.filter((el) => !!el)
.join('/');
}; };
const getNormalizedPost = async (post: CollectionEntry<'posts'>): Promise<Post> => { const getNormalizedPost = async (post: CollectionEntry<'post'>): Promise<Post> => {
const { id, slug: rawSlug = '', data } = post; const { id, slug: rawSlug = '', data } = post;
const { Content } = await post.render(); const { Content } = await post.render();
const { const {
tags: rawTags = [], tags: rawTags = [],
category: rawCategory = 'default', category: rawCategory,
author = 'Anonymous', author = 'Anonymous',
publishDate: rawPublishDate = new Date(), publishDate: rawPublishDate = new Date(),
...rest ...rest
@ -37,7 +42,7 @@ const getNormalizedPost = async (post: CollectionEntry<'posts'>): Promise<Post>
const slug = cleanSlug(rawSlug.split('/').pop()); const slug = cleanSlug(rawSlug.split('/').pop());
const publishDate = new Date(rawPublishDate); const publishDate = new Date(rawPublishDate);
const category = cleanSlug(rawCategory); const category = rawCategory ? cleanSlug(rawCategory) : undefined;
const tags = rawTags.map((tag: string) => cleanSlug(tag)); const tags = rawTags.map((tag: string) => cleanSlug(tag));
return { return {
@ -59,7 +64,7 @@ const getNormalizedPost = async (post: CollectionEntry<'posts'>): Promise<Post>
}; };
const load = async function (): Promise<Array<Post>> { const load = async function (): Promise<Array<Post>> {
const posts = await getCollection('posts'); const posts = await getCollection('post');
const normalizedPosts = posts.map(async (post) => await getNormalizedPost(post)); const normalizedPosts = posts.map(async (post) => await getNormalizedPost(post));
const results = (await Promise.all(normalizedPosts)) const results = (await Promise.all(normalizedPosts))

View File

@ -3,7 +3,7 @@ import slugify from 'limax';
import { SITE, BLOG } from '~/config.mjs'; import { SITE, BLOG } from '~/config.mjs';
import { trim } from '~/utils/utils'; import { trim } from '~/utils/utils';
const trimSlash = (s: string) => trim(trim(s, '/')); export const trimSlash = (s: string) => trim(trim(s, '/'));
const createPath = (...params: string[]) => { const createPath = (...params: string[]) => {
const paths = params const paths = params
.map((el) => trimSlash(el)) .map((el) => trimSlash(el))