mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-16 19:51:07 +02:00
feat: add custom slug validation and handling for posts
- Enhance content configuration with slug validation to ensure only valid characters are used - Update post routing to support custom slugs with fallback to default slug - Implement slug duplication check to prevent conflicts across different languages - Modify various page components to use custom or default slugs in URL generation
This commit is contained in:
parent
ee35006f7c
commit
a26031d490
10 changed files with 67 additions and 11 deletions
|
@ -21,7 +21,7 @@ const posts = await getPosts()
|
|||
<ul>
|
||||
{pinnedPosts.map(post => (
|
||||
<li>
|
||||
<a href={`/${lang}/posts/${post.slug}/`}>
|
||||
<a href={`/${lang}/posts/${post.data.slug || post.slug}/`}>
|
||||
{post.data.title}
|
||||
<time>({post.data.published.toISOString().split('T')[0]})</time>
|
||||
</a>
|
||||
|
@ -35,7 +35,7 @@ const posts = await getPosts()
|
|||
<ul>
|
||||
{posts.map(post => (
|
||||
<li>
|
||||
<a href={`/${lang}/posts/${post.slug}/`}>
|
||||
<a href={`/${lang}/posts/${post.data.slug || post.slug}/`}>
|
||||
{post.data.title}
|
||||
<time>({post.data.published.toISOString().split('T')[0]})</time>
|
||||
</a>
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
---
|
||||
import { themeConfig } from '@/config'
|
||||
import Layout from '@/layouts/Layout.astro'
|
||||
import { checkSlugDuplication } from '@/utils/content.config'
|
||||
import { getCollection } from 'astro:content'
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection('posts')
|
||||
|
||||
const duplicates = await checkSlugDuplication(posts)
|
||||
if (duplicates.length > 0) {
|
||||
throw new Error(`Slug conflicts found:\n${duplicates.join('\n')}`)
|
||||
}
|
||||
|
||||
return themeConfig.global.moreLocale.flatMap(lang =>
|
||||
posts.map(post => ({
|
||||
params: { lang, slug: post.slug },
|
||||
params: {
|
||||
lang,
|
||||
slug: post.data.slug || post.slug,
|
||||
},
|
||||
props: { post },
|
||||
})),
|
||||
)
|
||||
|
|
|
@ -65,7 +65,7 @@ export async function GET({ params }: APIContext) {
|
|||
pubDate: post.data.published,
|
||||
description: post.data.description || getExcerpt(post.body),
|
||||
// Generate absolute URL with language prefix
|
||||
link: new URL(`${lang}/posts/${post.slug}/`, url).toString(),
|
||||
link: new URL(`${lang}/posts/${post.data.slug || post.slug}/`, url).toString(),
|
||||
// Convert markdown content to HTML, allowing img tags
|
||||
content: post.body
|
||||
? sanitizeHtml(parser.render(post.body), {
|
||||
|
|
|
@ -32,7 +32,7 @@ const allTags = await getAllTags()
|
|||
<ul>
|
||||
{posts.map(post => (
|
||||
<li>
|
||||
<a href={`/${lang}/posts/${post.slug}/`}>{post.data.title}</a>
|
||||
<a href={`/${lang}/posts/${post.data.slug || post.slug}/`}>{post.data.title}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
|
|
@ -13,7 +13,7 @@ const pinnedPosts = await getPinnedPosts()
|
|||
<ul>
|
||||
{pinnedPosts.map(post => (
|
||||
<li>
|
||||
<a href={`/posts/${post.slug}/`}>
|
||||
<a href={`/posts/${post.data.slug || post.slug}/`}>
|
||||
{post.data.title}
|
||||
<time>({post.data.published.toISOString().split('T')[0]})</time>
|
||||
</a>
|
||||
|
@ -27,7 +27,7 @@ const pinnedPosts = await getPinnedPosts()
|
|||
<ul>
|
||||
{posts.map(post => (
|
||||
<li>
|
||||
<a href={`/posts/${post.slug}/`}>
|
||||
<a href={`/posts/${post.data.slug || post.slug}/`}>
|
||||
{post.data.title}
|
||||
<time>({post.data.published.toISOString().split('T')[0]})</time>
|
||||
</a>
|
||||
|
|
|
@ -1,11 +1,20 @@
|
|||
---
|
||||
import Layout from '@/layouts/Layout.astro'
|
||||
import { checkSlugDuplication } from '@/utils/content.config'
|
||||
import { getCollection } from 'astro:content'
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection('posts')
|
||||
|
||||
const duplicates = await checkSlugDuplication(posts)
|
||||
if (duplicates.length > 0) {
|
||||
throw new Error(`Slug conflicts found:\n${duplicates.join('\n')}`)
|
||||
}
|
||||
|
||||
return posts.map(post => ({
|
||||
params: { slug: post.slug },
|
||||
params: {
|
||||
slug: post.data.slug || post.slug,
|
||||
},
|
||||
props: { post },
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ export async function GET() {
|
|||
pubDate: post.data.published,
|
||||
description: post.data.description || getExcerpt(post.body),
|
||||
// Generate absolute URL for post
|
||||
link: new URL(`posts/${post.slug}/`, url).toString(),
|
||||
link: new URL(`posts/${post.data.slug || post.slug}/`, url).toString(),
|
||||
// Convert markdown content to HTML, allowing img tags
|
||||
content: post.body
|
||||
? sanitizeHtml(parser.render(post.body), {
|
||||
|
|
|
@ -28,7 +28,7 @@ const allTags = await getAllTags()
|
|||
<ul>
|
||||
{posts.map(post => (
|
||||
<li>
|
||||
<a href={`/posts/${post.slug}/`}>{post.data.title}</a>
|
||||
<a href={`/posts/${post.data.slug || post.slug}/`}>{post.data.title}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue