Skip to content

Commit

Permalink
Fix #397: Adjust URL for Chinese Categories and Tags
Browse files Browse the repository at this point in the history
  • Loading branch information
prototypa committed Apr 14, 2024
1 parent c830d68 commit f234e63
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 39 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@onwidget/astrowind",
"version": "1.0.0-beta.29",
"version": "1.0.0-beta.30",
"description": "AstroWind: A free template using Astro 4.0 and Tailwind CSS. Astro starter theme.",
"type": "module",
"private": true,
Expand Down
16 changes: 11 additions & 5 deletions src/components/blog/ListItem.astro
Original file line number Diff line number Diff line change
Expand Up @@ -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>
</>
)
Expand All @@ -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>
4 changes: 2 additions & 2 deletions src/components/blog/SinglePost.astro
Original file line number Diff line number Diff line change
Expand Up @@ -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>
</>
)
Expand Down
6 changes: 3 additions & 3 deletions src/components/blog/Tags.astro
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
6 changes: 3 additions & 3 deletions src/pages/[...blog]/[category]/[...page].astro
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/[...blog]/[tag]/[...page].astro
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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>
Expand Down
9 changes: 7 additions & 2 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ export interface Post {
image?: ImageMetadata | string;

/** */
category?: string;
category?: Taxonomy
/** */
tags?: Array<string>;
tags?: Taxonomy[];
/** */
author?: string;

Expand All @@ -44,6 +44,11 @@ export interface Post {
readingTime?: number;
}

export interface Taxonomy {
slug: string;
title: string;
}

export interface MetaData {
title?: string;
ignoreTitleTemplate?: boolean;
Expand Down
59 changes: 40 additions & 19 deletions src/utils/blog.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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] },
}
)
);
Expand All @@ -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);
Expand Down

0 comments on commit f234e63

Please sign in to comment.