diff --git a/package-lock.json b/package-lock.json
index a586de1..98043a8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@onwidget/astrowind",
- "version": "1.0.0-beta.29",
+ "version": "1.0.0-beta.30",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@onwidget/astrowind",
- "version": "1.0.0-beta.28",
+ "version": "1.0.0-beta.30",
"dependencies": {
"@astrojs/rss": "^4.0.5",
"@astrojs/sitemap": "^3.1.2",
diff --git a/package.json b/package.json
index 1f00648..6ae1319 100644
--- a/package.json
+++ b/package.json
@@ -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,
diff --git a/src/components/blog/ListItem.astro b/src/components/blog/ListItem.astro
index 3945062..dc964d2 100644
--- a/src/components/blog/ListItem.astro
+++ b/src/components/blog/ListItem.astro
@@ -64,8 +64,8 @@ const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post') :
<>
{' '}
·{' '}
-
- {post.category.replaceAll('-', ' ')}
+
+ {post.category.title}
>
)
@@ -87,8 +87,14 @@ const link = APP_BLOG?.post?.isEnabled ? getPermalink(post.permalink, 'post') :
{post.excerpt &&
{post.excerpt}
}
-
+ {
+ post.tags && Array.isArray(post.tags) ? (
+
+ ) : (
+
+ )
+ }
diff --git a/src/components/blog/SinglePost.astro b/src/components/blog/SinglePost.astro
index 9c181d2..11e543c 100644
--- a/src/components/blog/SinglePost.astro
+++ b/src/components/blog/SinglePost.astro
@@ -40,8 +40,8 @@ const { Content } = post;
<>
{' '}
·{' '}
-
- {post.category.replaceAll('-', ' ')}
+
+ {post.category.title}
>
)
diff --git a/src/components/blog/Tags.astro b/src/components/blog/Tags.astro
index 9dc1dc1..636a5de 100644
--- a/src/components/blog/Tags.astro
+++ b/src/components/blog/Tags.astro
@@ -24,13 +24,13 @@ const { tags, class: className = 'text-sm', title = undefined, isCategory = fals
{tags.map((tag) => (
{!APP_BLOG?.tag?.isEnabled ? (
- tag
+ tag.title
) : (
- {tag}
+ {tag.title}
)}
diff --git a/src/pages/[...blog]/[category]/[...page].astro b/src/pages/[...blog]/[category]/[...page].astro
index f2e6db7..e1c4ff6 100644
--- a/src/pages/[...blog]/[category]/[...page].astro
+++ b/src/pages/[...blog]/[category]/[...page].astro
@@ -13,14 +13,14 @@ export const getStaticPaths = (async ({ paginate }) => {
return await getStaticPathsBlogCategory({ paginate });
}) satisfies GetStaticPaths;
-type Props = InferGetStaticPropsType & { category: string };
+type Props = InferGetStaticPropsType & { category: Record };
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 = {
- {category.replaceAll('-', ' ')}
+ {category.title}
diff --git a/src/pages/[...blog]/[tag]/[...page].astro b/src/pages/[...blog]/[tag]/[...page].astro
index 4406560..86a767b 100644
--- a/src/pages/[...blog]/[tag]/[...page].astro
+++ b/src/pages/[...blog]/[tag]/[...page].astro
@@ -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 = {
- Tag: {tag}
+ Tag: {tag.title}
diff --git a/src/types.d.ts b/src/types.d.ts
index 31a82f4..d16bd01 100644
--- a/src/types.d.ts
+++ b/src/types.d.ts
@@ -24,9 +24,9 @@ export interface Post {
image?: ImageMetadata | string;
/** */
- category?: string;
+ category?: Taxonomy
/** */
- tags?: Array;
+ 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;
diff --git a/src/utils/blog.ts b/src/utils/blog.ts
index 7d70e19..4647de3 100644
--- a/src/utils/blog.ts
+++ b/src/utils/blog.ts
@@ -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 =
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> {
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();
+ 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();
+ 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) {
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);