🚀 refactor: unify page routing files

This commit is contained in:
radishzzz 2025-03-14 23:13:54 +00:00
parent d352b6fb65
commit 54902da6dd
19 changed files with 522 additions and 348 deletions

View file

@ -0,0 +1,47 @@
---
import { allLocales, defaultLocale } from '@/i18n/config'
import Layout from '@/layouts/Layout.astro'
export async function getStaticPaths() {
// 定义路径数组的类型
type PathItem = {
params: { about: string }
props: { lang: string }
}
const paths: PathItem[] = []
// 默认语言的关于页面
paths.push({
params: { about: 'about' },
props: { lang: defaultLocale },
})
// 更多语言的关于页面
allLocales.forEach((lang: string) => {
if (lang !== defaultLocale) {
paths.push({
params: { about: `${lang}/about` },
props: { lang },
})
}
})
return paths
}
const { lang } = Astro.props
---
<Layout>
<div class="uno-decorative-line"></div>
<div class="heti mt-4.375">
{lang === 'en'
? (
<p>Retypeset is a static blog theme based on the <a href="https://astro.build/">Astro</a> framework, inspired by <a href="https://astro-theme-typography.vercel.app/">Typography</a>. Retypeset establishes a new visual standard and reimagines the layout of all pages, offering a reading experience similar to paper books, reviving the beauty of typography. Details in every sight, elegance in every space.</p>
)
: (
<p>Retypeset 是一款基于<a href="https://astro.build/">Astro</a>框架的静态博客主题,设计灵感来自<a href="https://astro-theme-typography.vercel.app/">Typography</a>。本主题通过建立全新的视觉规范,对所有页面进行重新编排,打造纸质书页般的阅读体验,再现版式之美。所见皆为细节,方寸尽显优雅。</p>
)}
</div>
</Layout>

View file

@ -1,18 +1,41 @@
---
import PostList from '@/components/PostList.astro'
import { getMultiLangRoutes } from '@/i18n/route'
import { allLocales, defaultLocale } from '@/i18n/config'
import Layout from '@/layouts/Layout.astro'
import { getPinnedPosts, getPostsByYear } from '@/utils/content'
export function getStaticPaths() {
return getMultiLangRoutes()
export async function getStaticPaths() {
// 定义路径数组的类型
type PathItem = {
params: { index: string | undefined }
props: { lang: string }
}
const paths: PathItem[] = []
// 默认语言的首页
paths.push({
params: { index: undefined },
props: { lang: defaultLocale },
})
// 更多语言的首页
allLocales.forEach((lang: string) => {
if (lang !== defaultLocale) {
paths.push({
params: { index: lang },
props: { lang },
})
}
})
return paths
}
const { lang } = Astro.params
const { lang } = Astro.props
const pinnedPosts = await getPinnedPosts(lang)
const postsByYear = await getPostsByYear(lang)
---
<Layout>
<main>
<!-- Pinned Posts -->

View file

@ -0,0 +1,145 @@
---
import Comments from '@/components/Comments/index.astro'
import PostTime from '@/components/PostTime.astro'
import { allLocales, defaultLocale } from '@/i18n/config'
import Layout from '@/layouts/Layout.astro'
import { checkSlugDuplication } from '@/utils/content'
import { generateDescription } from '@/utils/description'
import { getCollection } from 'astro:content'
export async function getStaticPaths() {
const posts = await getCollection('posts')
const duplicates = await checkSlugDuplication(posts)
if (duplicates.length > 0) {
throw new Error(`Slug conflicts found:\n${duplicates.join('\n')}`)
}
// 创建slug到语言的映射
const slugToLangs: Record<string, string[]> = {}
// 填充映射
posts.forEach((post) => {
const slug = post.data.abbrlink || post.slug
const lang = post.data.lang || defaultLocale
// 如果文章没有指定语言,初始化为所有支持的语言
if (!slugToLangs[slug]) {
if (!post.data.lang) {
slugToLangs[slug] = [...allLocales] // 文章支持所有语言
}
else {
slugToLangs[slug] = [defaultLocale] // 仅默认语言和指定语言
}
}
if (!slugToLangs[slug].includes(lang)) {
slugToLangs[slug].push(lang)
}
})
// 定义路径数组的类型
type PathItem = {
params: { posts_slug: string }
props: { post: any, lang: string, supportedLangs: string[] }
}
const paths: PathItem[] = []
// 默认语言的文章页面 (没有语言前缀)
posts.forEach((post) => {
if (!post.data.draft) {
const slug = post.data.abbrlink || post.slug
paths.push({
params: { posts_slug: `posts/${slug}` },
props: {
post,
lang: defaultLocale,
supportedLangs: slugToLangs[slug] || [],
},
})
}
})
// 更多语言的文章页面 (有语言前缀)
allLocales.forEach((lang: string) => {
if (lang !== defaultLocale) {
posts.forEach((post) => {
if (!post.data.draft && (post.data.lang === lang || post.data.lang === '')) {
const slug = post.data.abbrlink || post.slug
paths.push({
params: { posts_slug: `${lang}/posts/${slug}` },
props: {
post,
lang,
supportedLangs: slugToLangs[slug] || [],
},
})
}
})
}
})
return paths
}
const { post, lang, supportedLangs } = Astro.props
const description = generateDescription(post)
const { Content, remarkPluginFrontmatter } = await post.render()
// 构建标签链接
function getTagUrl(tagName: string): string {
return lang === defaultLocale
? `/tags/${tagName}/`
: `/${lang}/tags/${tagName}/`
}
---
<Layout
postTitle={post.data.title}
postDescription={description}
postSlug={post.slug}
supportedLangs={supportedLangs}
>
<article class="heti mb-12.6">
<h1 class="post-title">
<span
transition:name={`post-${post.data.abbrlink || post.slug}`}
data-disable-transition-on-theme
>
{post.data.title}
</span>
</h1>
<div
class="mb-17 block c-primary font-time"
transition:name={`time-${post.data.abbrlink || post.slug}`}
data-disable-transition-on-theme
>
<!-- published and updated time -->
<PostTime
date={post.data.published}
updatedDate={post.data.updated}
minutes={remarkPluginFrontmatter.minutes}
/>
</div>
<Content />
</article>
<!-- Tags -->
{post.data.tags && post.data.tags.length > 0 && (
<div class="uno-decorative-line"></div>
<div class="uno-tags-wrapper">
{post.data.tags.map((tag: string) => (
<a
href={getTagUrl(tag)}
class="uno-tags-style"
>
{tag}
</a>
))}
</div>
)}
<Comments />
</Layout>

57
src/pages/[...tags].astro Normal file
View file

@ -0,0 +1,57 @@
---
import { allLocales, defaultLocale } from '@/i18n/config'
import Layout from '@/layouts/Layout.astro'
import { getAllTags } from '@/utils/content'
export async function getStaticPaths() {
// 定义路径数组的类型
type PathItem = {
params: { tags: string }
props: { lang: string }
}
const paths: PathItem[] = []
// 默认语言的标签索引页
paths.push({
params: { tags: 'tags' },
props: { lang: defaultLocale },
})
// 更多语言的标签索引页
allLocales.forEach((lang: string) => {
if (lang !== defaultLocale) {
paths.push({
params: { tags: `${lang}/tags` },
props: { lang },
})
}
})
return paths
}
const { lang } = Astro.props
const allTags = await getAllTags()
// 构建标签链接
function getTagUrl(tagName: string): string {
return lang === defaultLocale
? `/tags/${tagName}/`
: `/${lang}/tags/${tagName}/`
}
---
<Layout>
<div class="uno-decorative-line"></div>
<div class="uno-tags-wrapper">
{allTags.map(tagName => (
<a
href={getTagUrl(tagName)}
class="uno-tags-style"
>
{tagName}
</a>
))}
</div>
</Layout>

View file

@ -0,0 +1,73 @@
---
import PostList from '@/components/PostList.astro'
import { allLocales, defaultLocale } from '@/i18n/config'
import Layout from '@/layouts/Layout.astro'
import { getAllTags, getPostsByTag } from '@/utils/content'
export async function getStaticPaths() {
const tags = await getAllTags()
// 定义路径数组的类型
type PathItem = {
params: { tags_tag: string }
props: { tag: string, lang: string }
}
const paths: PathItem[] = []
// 默认语言的标签页面 (没有语言前缀)
tags.forEach((tag: string) => {
paths.push({
params: { tags_tag: `tags/${tag}` },
props: { tag, lang: defaultLocale },
})
})
// 更多语言的标签页面 (有语言前缀)
allLocales.forEach((lang: string) => {
if (lang !== defaultLocale) {
tags.forEach((tag: string) => {
paths.push({
params: { tags_tag: `${lang}/tags/${tag}` },
props: { tag, lang },
})
})
}
})
return paths
}
const { tag, lang } = Astro.props
const posts = await getPostsByTag(tag, lang)
const allTags = await getAllTags()
// 构建标签链接
function getTagUrl(tagName: string): string {
return lang === defaultLocale
? `/tags/${tagName}/`
: `/${lang}/tags/${tagName}/`
}
---
<Layout>
<div class="uno-decorative-line"></div>
<div class="uno-tags-wrapper">
{allTags.map(tagName => (
<a
href={getTagUrl(tagName)}
class={`uno-tags-style ${
tag === tagName
? 'uno-tag-active'
: ''
}`}
>
{tagName}
</a>
))}
</div>
<div class="mt-10.625">
<PostList posts={posts} lang={lang} />
</div>
</Layout>

View file

@ -1,15 +0,0 @@
---
import { getMultiLangRoutes } from '@/i18n/route'
import Layout from '@/layouts/Layout.astro'
export function getStaticPaths() {
return getMultiLangRoutes()
}
---
<Layout>
<div class="uno-decorative-line"></div>
<div class="heti mt-4.375">
<p>Retypeset is a static blog theme based on the <a href="https://astro.build/">Astro</a> framework, inspired by <a href="https://astro-theme-typography.vercel.app/">Typography</a>. Retypeset establishes a new visual standard and reimagines the layout of all pages, offering a reading experience similar to paper books, reviving the beauty of typography. Details in every sight, elegance in every space.</p>
</div>
</Layout>

View file

@ -1,74 +0,0 @@
---
import Comments from '@/components/Comments/index.astro'
import PostTime from '@/components/PostTime.astro'
import { getMultiLangPostRoutes } from '@/i18n/route'
import Layout from '@/layouts/Layout.astro'
import { checkSlugDuplication } from '@/utils/content'
import { generateDescription } from '@/utils/description'
import { getCollection } from 'astro:content'
export async function getStaticPaths() {
const posts = await getCollection('posts')
const duplicates = await checkSlugDuplication(posts)
if (duplicates.length > 0) {
throw new Error(`Slug conflicts found:\n${duplicates.join('\n')}`)
}
return getMultiLangPostRoutes(posts)
}
const { lang } = Astro.params
const { post, supportedLangs = [] } = Astro.props
const description = generateDescription(post)
const { Content, remarkPluginFrontmatter } = await post.render()
---
<Layout
postTitle={post.data.title}
postDescription={description}
postSlug={post.slug}
supportedLangs={supportedLangs}
>
<article class="heti mb-12.6">
<h1 class="post-title">
<span
transition:name={`post-${post.data.abbrlink || post.slug}`}
data-disable-transition-on-theme
>
{post.data.title}
</span>
</h1>
<div
class="mb-17 block c-primary font-time"
transition:name={`time-${post.data.abbrlink || post.slug}`}
data-disable-transition-on-theme
>
<!-- published and updated time -->
<PostTime
date={post.data.published}
updatedDate={post.data.updated}
minutes={remarkPluginFrontmatter.minutes}
/>
</div>
<Content />
</article>
<!-- Tags -->
{post.data.tags && post.data.tags.length > 0 && (
<div class="uno-decorative-line"></div>
<div class="uno-tags-wrapper">
{post.data.tags.map(tag => (
<a
href={`/${lang}/tags/${tag}/`}
class="uno-tags-style"
>
{tag}
</a>
))}
</div>
)}
<Comments />
</Layout>

View file

@ -1,38 +0,0 @@
---
import PostList from '@/components/PostList.astro'
import { getMultiLangTagRoutes } from '@/i18n/route'
import Layout from '@/layouts/Layout.astro'
import { getAllTags, getPostsByTag } from '@/utils/content'
export async function getStaticPaths() {
const tags = await getAllTags()
return getMultiLangTagRoutes(tags)
}
const { lang } = Astro.params
const { tag } = Astro.props
const posts = await getPostsByTag(tag, lang)
const allTags = await getAllTags()
---
<Layout>
<div class="uno-decorative-line"></div>
<div class="uno-tags-wrapper">
{allTags.map(tag => (
<a
href={`/${lang}/tags/${tag}/`}
class={`uno-tags-style ${
Astro.props.tag === tag
? 'uno-tag-active'
: ''
}`}
>
{tag}
</a>
))}
</div>
<div class="mt-10.625">
<PostList posts={posts} lang={lang} />
</div>
</Layout>

View file

@ -1,26 +0,0 @@
---
import { getMultiLangRoutes } from '@/i18n/route'
import Layout from '@/layouts/Layout.astro'
import { getAllTags } from '@/utils/content'
export function getStaticPaths() {
return getMultiLangRoutes()
}
const { lang } = Astro.params
const allTags = await getAllTags()
---
<Layout>
<div class="uno-decorative-line"></div>
<div class="uno-tags-wrapper">
{allTags.map(tag => (
<a
href={`/${lang}/tags/${tag}/`}
class="uno-tags-style"
>
{tag}
</a>
))}
</div>
</Layout>

View file

@ -1,10 +0,0 @@
---
import Layout from '@/layouts/Layout.astro'
---
<Layout>
<div class="uno-decorative-line"></div>
<div class="heti mt-4.375">
<p>Retypeset 是一款基于<a href="https://astro.build/">Astro</a>框架的静态博客主题,设计灵感来自<a href="https://astro-theme-typography.vercel.app/">Typography</a>。本主题通过建立全新的视觉规范,对所有页面进行重新编排,打造纸质书页般的阅读体验,再现版式之美。所见皆为细节,方寸尽显优雅。</p>
</div>
</Layout>

View file

@ -1,27 +0,0 @@
---
import PostList from '@/components/PostList.astro'
import Layout from '@/layouts/Layout.astro'
import { getPinnedPosts, getPostsByYear } from '@/utils/content'
const pinnedPosts = await getPinnedPosts()
const postsByYear = await getPostsByYear()
---
<Layout>
<main>
<!-- Pinned Posts -->
{pinnedPosts.length > 0 && (
<section class="mb-7.5">
<div class="uno-decorative-line"></div>
<PostList posts={pinnedPosts} />
</section>
)}
<!-- Regular Posts -->
{[...postsByYear.entries()].map(([_year, posts]) => (
<section class="mb-7.5">
<div class="uno-decorative-line"></div>
<PostList posts={posts} />
</section>
))}
</main>
</Layout>

View file

@ -1,73 +0,0 @@
---
import Comments from '@/components/Comments/index.astro'
import PostTime from '@/components/PostTime.astro'
import { getPostRoutes } from '@/i18n/route'
import Layout from '@/layouts/Layout.astro'
import { checkSlugDuplication } from '@/utils/content'
import { generateDescription } from '@/utils/description'
import { getCollection } from 'astro:content'
export async function getStaticPaths() {
const posts = await getCollection('posts')
const duplicates = await checkSlugDuplication(posts)
if (duplicates.length > 0) {
throw new Error(`Slug conflicts found:\n${duplicates.join('\n')}`)
}
return getPostRoutes(posts)
}
const { post, supportedLangs = [] } = Astro.props
const description = generateDescription(post)
const { Content, remarkPluginFrontmatter } = await post.render()
---
<Layout
postTitle={post.data.title}
postDescription={description}
postSlug={post.slug}
supportedLangs={supportedLangs}
>
<article class="heti mb-12.6">
<h1 class="post-title">
<span
transition:name={`post-${post.data.abbrlink || post.slug}`}
data-disable-transition-on-theme
>
{post.data.title}
</span>
</h1>
<div
class="mb-17 block c-primary font-time"
transition:name={`time-${post.data.abbrlink || post.slug}`}
data-disable-transition-on-theme
>
<!-- published and updated time -->
<PostTime
date={post.data.published}
updatedDate={post.data.updated}
minutes={remarkPluginFrontmatter.minutes}
/>
</div>
<Content />
</article>
<!-- Tags -->
{post.data.tags && post.data.tags.length > 0 && (
<div class="uno-decorative-line"></div>
<div class="uno-tags-wrapper">
{post.data.tags.map(tag => (
<a
href={`/tags/${tag}/`}
class="uno-tags-style"
>
{tag}
</a>
))}
</div>
)}
<Comments />
</Layout>

View file

@ -1,37 +0,0 @@
---
import PostList from '@/components/PostList.astro'
import { getTagRoutes } from '@/i18n/route'
import Layout from '@/layouts/Layout.astro'
import { getAllTags, getPostsByTag } from '@/utils/content'
export async function getStaticPaths() {
const tags = await getAllTags()
return getTagRoutes(tags)
}
const { tag } = Astro.props
const posts = await getPostsByTag(tag)
const allTags = await getAllTags()
---
<Layout>
<div class="uno-decorative-line"></div>
<div class="uno-tags-wrapper">
{allTags.map(tag => (
<a
href={`/tags/${tag}/`}
class={`uno-tags-style ${
Astro.props.tag === tag
? 'uno-tag-active'
: ''
}`}
>
{tag}
</a>
))}
</div>
<div class="mt-10.625">
<PostList posts={posts} />
</div>
</Layout>

View file

@ -1,20 +0,0 @@
---
import Layout from '@/layouts/Layout.astro'
import { getAllTags } from '@/utils/content'
const allTags = await getAllTags()
---
<Layout>
<div class="uno-decorative-line"></div>
<div class="uno-tags-wrapper">
{allTags.map(tag => (
<a
href={`/tags/${tag}/`}
class="uno-tags-style"
>
{tag}
</a>
))}
</div>
</Layout>