Fix #397: Adjust URL for Chinese Categories and Tags
This commit is contained in:
@@ -64,8 +64,8 @@ const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post') :
|
||||
<>
|
||||
{' '}
|
||||
·{' '}
|
||||
<a class="capitalize hover:underline" href={getPermalink(post.category, 'category')}>
|
||||
{post.category.replaceAll('-', ' ')}
|
||||
<a class="hover:underline" href={getPermalink(post.category.slug, 'category')}>
|
||||
{post.category.title}
|
||||
</a>
|
||||
</>
|
||||
)
|
||||
@@ -87,8 +87,14 @@ const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post') :
|
||||
</header>
|
||||
|
||||
{post.excerpt && <p class="flex-grow text-muted dark:text-slate-400 text-lg">{post.excerpt}</p>}
|
||||
<footer class="mt-5">
|
||||
<PostTags tags={post.tags} />
|
||||
</footer>
|
||||
{
|
||||
post.tags && Array.isArray(post.tags) ? (
|
||||
<footer class="mt-5">
|
||||
<PostTags tags={post.tags} />
|
||||
</footer>
|
||||
) : (
|
||||
<Fragment />
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</article>
|
||||
|
@@ -40,8 +40,8 @@ const { Content } = post;
|
||||
<>
|
||||
{' '}
|
||||
·{' '}
|
||||
<a class="capitalize hover:underline inline-block" href={getPermalink(post.category, 'category')}>
|
||||
{post.category.replaceAll('-', ' ')}
|
||||
<a class="hover:underline inline-block" href={getPermalink(post.category.slug, 'category')}>
|
||||
{post.category.title}
|
||||
</a>
|
||||
</>
|
||||
)
|
||||
|
@@ -24,13 +24,13 @@ const { tags, class: className = 'text-sm', title = undefined, isCategory = fals
|
||||
{tags.map((tag) => (
|
||||
<li class="bg-gray-100 dark:bg-slate-700 inline-block mr-2 rtl:mr-0 rtl:ml-2 mb-2 py-0.5 px-2 lowercase font-medium">
|
||||
{!APP_BLOG?.tag?.isEnabled ? (
|
||||
tag
|
||||
tag.title
|
||||
) : (
|
||||
<a
|
||||
href={getPermalink(tag, (isCategory ? 'category' : 'tag'))}
|
||||
href={getPermalink(tag.slug, (isCategory ? 'category' : 'tag'))}
|
||||
class="text-muted dark:text-slate-300 hover:text-primary dark:hover:text-gray-200"
|
||||
>
|
||||
{tag}
|
||||
{tag.title}
|
||||
</a>
|
||||
)}
|
||||
</li>
|
||||
|
@@ -13,14 +13,14 @@ export const getStaticPaths = (async ({ paginate }) => {
|
||||
return await getStaticPathsBlogCategory({ paginate });
|
||||
}) satisfies GetStaticPaths;
|
||||
|
||||
type Props = InferGetStaticPropsType<typeof getStaticPaths> & { category: string };
|
||||
type Props = InferGetStaticPropsType<typeof getStaticPaths> & { category: Record<string, string> };
|
||||
|
||||
const { page, category } = Astro.props as Props;
|
||||
|
||||
const currentPage = page.currentPage ?? 1;
|
||||
|
||||
const metadata = {
|
||||
title: `Category '${category}' ${currentPage > 1 ? ` — Page ${currentPage}` : ''}`,
|
||||
title: `Category '${category.title}' ${currentPage > 1 ? ` — Page ${currentPage}` : ''}`,
|
||||
robots: {
|
||||
index: blogCategoryRobots?.index,
|
||||
follow: blogCategoryRobots?.follow,
|
||||
@@ -30,7 +30,7 @@ const metadata = {
|
||||
|
||||
<Layout metadata={metadata}>
|
||||
<section class="px-4 md:px-6 py-12 sm:py-16 lg:py-20 mx-auto max-w-4xl">
|
||||
<Headline><span class="capitalize">{category.replaceAll('-', ' ')}</span></Headline>
|
||||
<Headline>{category.title}</Headline>
|
||||
<BlogList posts={page.data} />
|
||||
<Pagination prevUrl={page.url.prev} nextUrl={page.url.next} />
|
||||
</section>
|
||||
|
@@ -20,7 +20,7 @@ const { page, tag } = Astro.props as Props;
|
||||
const currentPage = page.currentPage ?? 1;
|
||||
|
||||
const metadata = {
|
||||
title: `Posts by tag '${tag}'${currentPage > 1 ? ` — Page ${currentPage} ` : ''}`,
|
||||
title: `Posts by tag '${tag.title}'${currentPage > 1 ? ` — Page ${currentPage} ` : ''}`,
|
||||
robots: {
|
||||
index: blogTagRobots?.index,
|
||||
follow: blogTagRobots?.follow,
|
||||
@@ -30,7 +30,7 @@ const metadata = {
|
||||
|
||||
<Layout metadata={metadata}>
|
||||
<section class="px-4 md:px-6 py-12 sm:py-16 lg:py-20 mx-auto max-w-4xl">
|
||||
<Headline>Tag: {tag}</Headline>
|
||||
<Headline>Tag: {tag.title}</Headline>
|
||||
<BlogList posts={page.data} />
|
||||
<Pagination prevUrl={page.url.prev} nextUrl={page.url.next} />
|
||||
</section>
|
||||
|
9
src/types.d.ts
vendored
9
src/types.d.ts
vendored
@@ -24,9 +24,9 @@ export interface Post {
|
||||
image?: ImageMetadata | string;
|
||||
|
||||
/** */
|
||||
category?: string;
|
||||
category?: Taxonomy
|
||||
/** */
|
||||
tags?: Array<string>;
|
||||
tags?: Taxonomy[];
|
||||
/** */
|
||||
author?: string;
|
||||
|
||||
@@ -44,6 +44,11 @@ export interface Post {
|
||||
readingTime?: number;
|
||||
}
|
||||
|
||||
export interface Taxonomy {
|
||||
slug: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface MetaData {
|
||||
title?: string;
|
||||
ignoreTitleTemplate?: boolean;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import type { PaginateFunction } from 'astro';
|
||||
import { getCollection } from 'astro:content';
|
||||
import type { CollectionEntry } from 'astro:content';
|
||||
import type { Post } from '~/types';
|
||||
import type { Post, Taxonomy } from '~/types';
|
||||
import { APP_BLOG } from 'astrowind:config';
|
||||
import { cleanSlug, trimSlash, BLOG_BASE, POST_PERMALINK_PATTERN, CATEGORY_BASE, TAG_BASE } from './permalinks';
|
||||
|
||||
@@ -60,13 +60,23 @@ const getNormalizedPost = async (post: CollectionEntry<'post'>): Promise<Post> =
|
||||
const slug = cleanSlug(rawSlug); // cleanSlug(rawSlug.split('/').pop());
|
||||
const publishDate = new Date(rawPublishDate);
|
||||
const updateDate = rawUpdateDate ? new Date(rawUpdateDate) : undefined;
|
||||
const category = rawCategory ? cleanSlug(rawCategory) : undefined;
|
||||
const tags = rawTags.map((tag: string) => cleanSlug(tag));
|
||||
|
||||
const category = rawCategory
|
||||
? {
|
||||
slug: cleanSlug(rawCategory),
|
||||
title: rawCategory,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
const tags = rawTags.map((tag: string) => ({
|
||||
slug: cleanSlug(tag),
|
||||
title: tag,
|
||||
}));
|
||||
|
||||
return {
|
||||
id: id,
|
||||
slug: slug,
|
||||
permalink: await generatePermalink({ id, slug, publishDate, category }),
|
||||
permalink: await generatePermalink({ id, slug, publishDate, category: category?.slug }),
|
||||
|
||||
publishDate: publishDate,
|
||||
updateDate: updateDate,
|
||||
@@ -102,6 +112,17 @@ const getRandomizedPosts = (array: Post[], num: number) => {
|
||||
return newArray;
|
||||
};
|
||||
|
||||
function hasMatchingTaxonomies(
|
||||
arr1?: Taxonomy[],
|
||||
arr2?: Taxonomy[]
|
||||
): boolean {
|
||||
if (!arr1 || !arr2) {
|
||||
return false;
|
||||
}
|
||||
const slugsSet = new Set(arr1.map((item) => item.slug));
|
||||
return arr2.some((item) => slugsSet.has(item.slug));
|
||||
}
|
||||
|
||||
const load = async function (): Promise<Array<Post>> {
|
||||
const posts = await getCollection('post');
|
||||
const normalizedPosts = posts.map(async (post) => await getNormalizedPost(post));
|
||||
@@ -200,18 +221,18 @@ export const getStaticPathsBlogCategory = async ({ paginate }: { paginate: Pagin
|
||||
if (!isBlogEnabled || !isBlogCategoryRouteEnabled) return [];
|
||||
|
||||
const posts = await fetchPosts();
|
||||
const categories = new Set<string>();
|
||||
const categories = {};
|
||||
posts.map((post) => {
|
||||
typeof post.category === 'string' && categories.add(post.category.toLowerCase());
|
||||
post.category?.slug && (categories[post.category?.slug] = post.category);
|
||||
});
|
||||
|
||||
return Array.from(categories).flatMap((category) =>
|
||||
return Array.from(Object.keys(categories)).flatMap((categorySlug) =>
|
||||
paginate(
|
||||
posts.filter((post) => typeof post.category === 'string' && category === post.category.toLowerCase()),
|
||||
posts.filter((post) => post.category?.slug && categorySlug === post.category?.slug),
|
||||
{
|
||||
params: { category: category, blog: CATEGORY_BASE || undefined },
|
||||
params: { category: categorySlug, blog: CATEGORY_BASE || undefined },
|
||||
pageSize: blogPostsPerPage,
|
||||
props: { category },
|
||||
props: { category: categories[categorySlug] },
|
||||
}
|
||||
)
|
||||
);
|
||||
@@ -222,35 +243,35 @@ export const getStaticPathsBlogTag = async ({ paginate }: { paginate: PaginateFu
|
||||
if (!isBlogEnabled || !isBlogTagRouteEnabled) return [];
|
||||
|
||||
const posts = await fetchPosts();
|
||||
const tags = new Set<string>();
|
||||
const tags = {};
|
||||
posts.map((post) => {
|
||||
Array.isArray(post.tags) && post.tags.map((tag) => tags.add(tag.toLowerCase()));
|
||||
Array.isArray(post.tags) && post.tags.map((tag) => { tags[tag?.slug] = tag; });
|
||||
});
|
||||
|
||||
return Array.from(tags).flatMap((tag) =>
|
||||
return Array.from(Object.keys(tags)).flatMap((tagSlug) =>
|
||||
paginate(
|
||||
posts.filter((post) => Array.isArray(post.tags) && post.tags.find((elem) => elem.toLowerCase() === tag)),
|
||||
posts.filter((post) => Array.isArray(post.tags) && post.tags.find((elem) => elem.slug === tagSlug)),
|
||||
{
|
||||
params: { tag: tag, blog: TAG_BASE || undefined },
|
||||
params: { tag: tagSlug, blog: TAG_BASE || undefined },
|
||||
pageSize: blogPostsPerPage,
|
||||
props: { tag },
|
||||
props: { tag: tags[tagSlug] },
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
/** */
|
||||
export function getRelatedPosts(allPosts: Post[], currentSlug: string, currentTags: string[]) {
|
||||
export function getRelatedPosts(allPosts: Post[], currentSlug: string, currentTags: Array<Taxonomy>) {
|
||||
if (!isBlogEnabled || !isRelatedPostsEnabled) return [];
|
||||
|
||||
const relatedPosts = getRandomizedPosts(
|
||||
allPosts.filter((post) => post.slug !== currentSlug && post.tags?.some((tag) => currentTags.includes(tag))),
|
||||
allPosts.filter((post) => post.slug !== currentSlug && hasMatchingTaxonomies(post.tags, currentTags)),
|
||||
APP_BLOG.relatedPostsCount
|
||||
);
|
||||
|
||||
if (relatedPosts.length < APP_BLOG.relatedPostsCount) {
|
||||
const morePosts = getRandomizedPosts(
|
||||
allPosts.filter((post) => post.slug !== currentSlug && !post.tags?.some((tag) => currentTags.includes(tag))),
|
||||
allPosts.filter((post) => post.slug !== currentSlug && hasMatchingTaxonomies(post.tags, currentTags)),
|
||||
APP_BLOG.relatedPostsCount - relatedPosts.length
|
||||
);
|
||||
relatedPosts.push(...morePosts);
|
||||
|
Reference in New Issue
Block a user