11---
2- import { type CollectionEntry } from ' astro:content' ;
3- import Layout from ' @/layouts/Layout.astro' ;
4- import BlogCard from ' @/components/blog/BlogCard.astro' ;
5- import Pagination from ' @/components/common/Pagination.astro' ;
6- import { useTranslations , getLocalizedPath , slugifyTag , isValidLanguage } from ' @/i18n/utils' ;
7- import { BlogService } from ' @/services/BlogService' ;
8- import { LOCALES , PAGINATION_TAGS_PER_PAGE } from ' @/consts' ;
9- import type { GetStaticPaths , Page } from ' astro' ;
2+ import { type CollectionEntry } from " astro:content" ;
3+ import Layout from " @/layouts/Layout.astro" ;
4+ import BlogCard from " @/components/blog/BlogCard.astro" ;
5+ import Pagination from " @/components/common/Pagination.astro" ;
6+ import { useTranslations , getLocalizedPath , slugifyTag , isValidLanguage } from " @/i18n/utils" ;
7+ import { BlogService } from " @/services/BlogService" ;
8+ import { LOCALES , PAGINATION_TAGS_PER_PAGE } from " @/consts" ;
9+ import type { GetStaticPaths , Page } from " astro" ;
1010
1111export const getStaticPaths = (async ({ paginate }) => {
1212 const languages = Object .keys (LOCALES );
@@ -17,10 +17,10 @@ export const getStaticPaths = (async ({ paginate }) => {
1717 const posts = await BlogService .getPostsByLocale (locale );
1818
1919 // Group posts by tag
20- const tagsMap = new Map <string , CollectionEntry <' blog' >[]>();
20+ const tagsMap = new Map <string , CollectionEntry <" blog" >[]>();
2121 posts .forEach (post => {
2222 (post .data .tags || []).forEach (tag => {
23- const normalizedTag = tag .trim ().normalize (' NFC' );
23+ const normalizedTag = tag .trim ().normalize (" NFC" );
2424 const existing = tagsMap .get (normalizedTag ) || [];
2525 existing .push (post );
2626 tagsMap .set (normalizedTag , existing );
@@ -52,11 +52,11 @@ export const getStaticPaths = (async ({ paginate }) => {
5252 page .url = {
5353 ... page .url ,
5454 prev: currentPage === 2
55- ? getLocalizedPath (' /blog/tags' , locale )
56- : page .url .prev ?.replace (/ \/ 1$ / , ' ' ),
55+ ? getLocalizedPath (" /blog/tags" , locale )
56+ : page .url .prev ?.replace (/ \/ 1$ / , " " ),
5757 next: page .url .next ,
58- current: page .url .current .replace (/ \/ 1$ / , ' ' ),
59- first: getLocalizedPath (' /blog/tags' , locale ),
58+ current: page .url .current .replace (/ \/ 1$ / , " " ),
59+ first: getLocalizedPath (" /blog/tags" , locale ),
6060 };
6161
6262 return {
@@ -70,7 +70,17 @@ export const getStaticPaths = (async ({ paginate }) => {
7070
7171 // 2. Individual Tag Page Paths
7272 const uniqueTags = Array .from (tagsMap .keys ());
73- for (const tag of uniqueTags ) {
73+ const { tagMappings } = await import (" @/i18n/tag-mappings" );
74+
75+ // Add mapped tags as well
76+ const allKnownTags = new Set (uniqueTags );
77+ Object .keys (tagMappings ).forEach (engSlug => {
78+ if (tagMappings [engSlug ][lang ]) {
79+ allKnownTags .add (tagMappings [engSlug ][lang ]);
80+ }
81+ });
82+
83+ for (const tag of allKnownTags ) {
7484 const tagSlug = slugifyTag (tag );
7585 if (tagSlug ) {
7686 // We don't paginate posts within a tag here to keep it simple as per original [tag].astro
@@ -86,34 +96,34 @@ export const getStaticPaths = (async ({ paginate }) => {
8696}) satisfies GetStaticPaths ;
8797
8898type Props =
89- | { isIndex: true ; page: Page <{ tag: string ; posts: CollectionEntry <' blog' >[]; count: number }>; tag? : undefined }
99+ | { isIndex: true ; page: Page <{ tag: string ; posts: CollectionEntry <" blog" >[]; count: number }>; tag? : undefined }
90100 | { isIndex: false ; page? : undefined ; tag: string };
91101
92102const { page, tag, isIndex } = Astro .props as Props ;
93103const { lang } = Astro .params ;
94104
95105if (! lang || ! isValidLanguage (lang )) {
96- return Astro .redirect (' /404' );
106+ return Astro .redirect (" /404" );
97107}
98108
99109const locale = lang as any ;
100110const t = useTranslations (locale );
101111
102112// Prepare data for rendering
103- let tagPosts: CollectionEntry <' blog' >[] = [];
113+ let tagPosts: CollectionEntry <" blog" >[] = [];
104114if (! isIndex && tag ) {
105115 tagPosts = await BlogService .getPostsByTag (lang , tag );
106116}
107117---
108118
109119<Layout
110120 title ={ isIndex
111- ? ` ${t (' nav.tags' )} ${page && page .currentPage > 1 ? ` | ${t (' pagination.page' )} ${page .currentPage } ` : ' ' } | ${t (' nav.blog' )} `
112- : ` #${tag } | ${t (' nav.blog' )} `
121+ ? ` ${t (" nav.tags" )} ${page && page .currentPage > 1 ? ` | ${t (" pagination.page" )} ${page .currentPage } ` : " " } | ${t (" nav.blog" )} `
122+ : ` #${tag } | ${t (" nav.blog" )} `
113123 }
114124 description ={ isIndex
115- ? (locale === ' es ' ? ' Explora todos los temas de nuestro blog por etiquetas.' : locale === ' ja ' ? ' タグでブログのすべてのトピックを探索します。 ' : ' Explore all topics in our blog by tags.' )
116- : (locale === ' es ' ? ` Artículos sobre ${tag } ` : locale === ' ja ' ? ` ${tag }に関する記事 ` : ` Articles about ${tag } ` )
125+ ? (locale === " es " ? " Explora todos los temas de nuestro blog por etiquetas." : locale === " ja " ? " タグでブログのす べてのトピックを探索します。 " : " Explore all topics in our blog by tags." )
126+ : (locale === " es " ? ` Artículos sobre ${tag } ` : locale === " ja " ? ` ${tag }に関する記事 ` : ` Articles about ${tag } ` )
117127 }
118128 lang ={ locale }
119129>
@@ -122,14 +132,14 @@ if (!isIndex && tag) {
122132 <>
123133 <div class = " mb-16 text-center" >
124134 <h1 class = " mb-4 text-4xl font-bold text-slate-900 dark:text-white sm:text-5xl" >
125- { t (' nav.tags' )}
135+ { t (" nav.tags" )}
126136 </h1 >
127137 <p class = " mx-auto max-w-2xl text-lg text-slate-600 dark:text-slate-400 sm:text-xl" >
128- { locale === ' es '
129- ? ' Encuentra artículos por tema y categoría.'
130- : locale === ' ja '
131- ? ' トピックやカテゴリー別に記事を見つける。'
132- : ' Find articles by topic and category.' }
138+ { locale === " es "
139+ ? " Encuentra artículos por tema y categoría."
140+ : locale === " ja "
141+ ? " トピックやカテゴリー別に記事を見つける。"
142+ : " Find articles by topic and category." }
133143 </p >
134144 </div >
135145
@@ -152,14 +162,14 @@ if (!isIndex && tag) {
152162 </a >
153163 </h2 >
154164 <span class = " inline-flex shrink-0 items-center rounded-full bg-blue-100 px-3 py-1 text-xs font-semibold text-blue-600 dark:bg-blue-900/30 dark:text-blue-400" >
155- { count } { count === 1 ? t (' blog.post' ) : t (' blog.posts' )}
165+ { count } { count === 1 ? t (" blog.post" ) : t (" blog.posts" )}
156166 </span >
157167 </div >
158168 <a
159169 href = { getLocalizedPath (` /blog/tags/${slugifyTag (tagName )} ` , locale )}
160170 class = " inline-flex shrink-0 items-center gap-1 text-sm font-medium text-blue-600 transition-colors hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
161171 >
162- { t (' blog.viewTagArticles' )}
172+ { t (" blog.viewTagArticles" )}
163173 <svg xmlns = " http://www.w3.org/2000/svg" class = " h-4 w-4" viewBox = " 0 0 20 20" fill = " currentColor" >
164174 <path fill-rule = " evenodd" d = " M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule = " evenodd" />
165175 </svg >
@@ -171,7 +181,7 @@ if (!isIndex && tag) {
171181 <BlogCard
172182 post = { post }
173183 lang = { locale }
174- loading = { index < 3 ? ' eager' : ' lazy' }
184+ loading = { index < 3 ? " eager" : " lazy" }
175185 class = " post-item animate-fade-in"
176186 />
177187 ))}
@@ -180,36 +190,33 @@ if (!isIndex && tag) {
180190 ))}
181191 </div >
182192
183- { /* Pagination */ }
184193 { page && page .lastPage > 1 && <Pagination page = { page } lang = { locale } />}
185194 </>
186195 ) : (
187196 <div class = " py-20 text-center" >
188197 <p class = " text-xl text-slate-500" >
189- { locale === ' es ' ? ' No se encontraron etiquetas.' : locale === ' ja ' ? ' タグが見つかりません。' : ' No tags found.' }
198+ { locale === " es " ? " No se encontraron etiquetas." : locale === " ja " ? " タグが見つかりません。" : " No tags found." }
190199 </p >
191200 </div >
192201 )}
193202 </>
194203 ) : (
195204 <>
196- { /* Header */ }
197205 <div class = " mb-12 text-center" >
198206 <h1 class = " mb-4 text-4xl font-bold text-gray-900 dark:text-gray-100 sm:text-5xl" >
199207 #{ tag }
200208 </h1 >
201209 <p class = " mx-auto max-w-3xl text-xl text-gray-600 dark:text-gray-300" >
202210 {
203- locale === ' es '
211+ locale === " es "
204212 ? ` Artículos etiquetados con #${tag } `
205- : locale === ' ja '
213+ : locale === " ja "
206214 ? ` #${tag } のタグが付いた記事 `
207215 : ` Articles tagged with #${tag } `
208216 }
209217 </p >
210218 </div >
211219
212- { /* Posts Grid */ }
213220 { tagPosts .length > 0 ? (
214221 <div
215222 id = " posts-container"
@@ -219,19 +226,19 @@ if (!isIndex && tag) {
219226 <BlogCard
220227 post = { post }
221228 lang = { lang }
222- loading = { index < 3 ? ' eager' : ' lazy' }
229+ loading = { index < 3 ? " eager" : " lazy" }
223230 class = " post-item animate-fade-in"
224231 />
225232 ))}
226233 </div >
227234 ) : (
228235 <div class = " py-12 text-center" >
229236 <p class = " text-gray-500 dark:text-gray-400" >
230- { locale === ' es '
231- ? ' No se encontraron artículos.'
232- : locale === ' ja '
233- ? ' 記事が見つかりません。'
234- : ' No articles found.' }
237+ { locale === " es "
238+ ? " No se encontraron artículos."
239+ : locale === " ja "
240+ ? " 記事が見つかりません。"
241+ : " No articles found." }
235242 </p >
236243 </div >
237244 )}
0 commit comments