Update post collection and show category on posts
This commit is contained in:
@ -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} />
|
||||||
|
@ -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">
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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>
|
||||||
|
@ -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))
|
||||||
|
@ -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))
|
||||||
|
Reference in New Issue
Block a user