();
- posts.forEach((post) => {
- post.data.destination?.forEach((d) => destinations.add(d));
- });
-
- return Array.from(destinations).flatMap((destination) => {
- const destinationPosts = posts
- .filter((post) => post.data.destination?.includes(destination))
- .sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
-
- return paginate(destinationPosts, {
- params: { destination },
- pageSize: 6,
- });
- });
-}
-
-const { page } = Astro.props;
-const { destination } = Astro.params;
-
-const metadata = {
- title: `Destination: ${destination}`,
- description: `Travel articles about ${destination}.`,
-};
----
-
-
-
-
-
-
-
-
-
- {page.data.map((post) =>
)}
-
-
-
-
-
diff --git a/src/pages/tag/[tag]/[...page].astro b/src/pages/tag/[tag]/[...page].astro
index bffeb93..2065677 100644
--- a/src/pages/tag/[tag]/[...page].astro
+++ b/src/pages/tag/[tag]/[...page].astro
@@ -5,6 +5,7 @@ import Headline from "@/components/ui/Headline.astro";
import PostItem from "@/components/blog/PostItem.astro";
import Pagination from "@/components/ui/Pagination.astro";
import type { GetStaticPathsOptions } from "astro";
+import { tagMap } from "@/utils/taxonomy";
export async function getStaticPaths({ paginate }: GetStaticPathsOptions) {
const allPosts = await getCollection("blog");
@@ -30,9 +31,13 @@ export async function getStaticPaths({ paginate }: GetStaticPathsOptions) {
const { page } = Astro.props;
const { tag } = Astro.params;
+const tagInfo = tagMap.get(tag!);
+const displayName = tagInfo?.name ?? tag!;
+const description = tagInfo?.description;
+
const metadata = {
- title: `Posts tagged with '${tag}'`,
- description: `Explore our articles about ${tag}.`,
+ title: displayName,
+ description: description ?? `Các bài viết được gắn thẻ ${displayName}.`,
};
---
@@ -41,8 +46,8 @@ const metadata = {
;
+
+function buildMap(data: unknown[]): TaxonomyMap {
+ return new Map((data as TaxonomyItem[]).map((item) => [item.slug, item]));
+}
+
+const taxonomies: Record = {
+ category: buildMap(categoryData),
+ destination: buildMap(destinationData),
+ tag: buildMap(tagData),
+};
+
+export function getTaxonomyMap(type: string): TaxonomyMap {
+ return taxonomies[type] ?? new Map();
+}
+
+export function registerTaxonomy(type: string, data: TaxonomyItem[]): void {
+ taxonomies[type] = buildMap(data);
+}
+
+function buildHierarchicalPath(
+ slug: string,
+ map: TaxonomyMap,
+ visited = new Set(),
+): string {
+ if (visited.has(slug)) return slug; // cycle protection
+ visited.add(slug);
+ const item = map.get(slug);
+ if (!item?.parent) return slug;
+ return `${buildHierarchicalPath(item.parent, map, new Set(visited))}/${slug}`;
+}
+
+export function getTaxonomyPath(type: string, slug: string): string {
+ return buildHierarchicalPath(slug, getTaxonomyMap(type));
+}
+
+export function getTaxonomyItem(
+ type: string,
+ slug: string,
+): TaxonomyItem | undefined {
+ return getTaxonomyMap(type).get(slug);
+}
+
+// Convenience aliases kept for backward compatibility
+export const categoryMap = getTaxonomyMap("category");
+export const destinationMap = getTaxonomyMap("destination");
+export const tagMap = getTaxonomyMap("tag");
+
+export const getCategoryPath = (slug: string) =>
+ getTaxonomyPath("category", slug);
+export const getDestinationPath = (slug: string) =>
+ getTaxonomyPath("destination", slug);
+export const getTagPath = (slug: string) => getTaxonomyPath("tag", slug);