From 4651828dd130da17095a216e544aea0b44c1bc96 Mon Sep 17 00:00:00 2001 From: radishzzz Date: Fri, 14 Mar 2025 00:51:54 +0000 Subject: [PATCH] test: language switcher and i18n refactor --- package.json | 2 +- src/components/MainHeader.astro | 2 +- src/components/MobileHeader.astro | 2 +- src/components/Navbar.astro | 2 +- src/components/PostList.astro | 8 +- src/components/PostTime.astro | 2 +- src/components/Widgets/LanguageSwitcher.astro | 134 ++---------------- src/layouts/Layout.astro | 2 +- src/utils/i18n/lang.ts | 106 ++++++++++++++ src/utils/{ => i18n}/path.ts | 0 10 files changed, 127 insertions(+), 133 deletions(-) create mode 100644 src/utils/i18n/lang.ts rename src/utils/{ => i18n}/path.ts (100%) diff --git a/package.json b/package.json index ed5984d..f96448c 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "astro-theme-retypeset", "type": "module", "version": "0.0.1", - "packageManager": "pnpm@10.6.2", + "packageManager": "pnpm@10.6.3", "scripts": { "dev": "astro dev", "build": "astro build", diff --git a/src/components/MainHeader.astro b/src/components/MainHeader.astro index 3300965..f57d944 100644 --- a/src/components/MainHeader.astro +++ b/src/components/MainHeader.astro @@ -1,6 +1,6 @@ --- import themeConfig from '@/config' -import { getPagePath } from '@/utils/path' +import { getPagePath } from '@/utils/i18n/path' const { title, subtitle } = themeConfig.site const { titleSpace } = themeConfig.global diff --git a/src/components/MobileHeader.astro b/src/components/MobileHeader.astro index a16bb04..b9230ca 100644 --- a/src/components/MobileHeader.astro +++ b/src/components/MobileHeader.astro @@ -1,6 +1,6 @@ --- import themeConfig from '@/config' -import { getPagePath } from '@/utils/path' +import { getPagePath } from '@/utils/i18n/path' const { title, subtitle } = themeConfig.site const { titleSpace } = themeConfig.global diff --git a/src/components/Navbar.astro b/src/components/Navbar.astro index 46f2e01..11c6bd8 100644 --- a/src/components/Navbar.astro +++ b/src/components/Navbar.astro @@ -1,6 +1,6 @@ --- +import { getPagePath } from '@/utils/i18n/path' import { ui } from '@/utils/i18n/ui' -import { getPagePath } from '@/utils/path' const currentPath = Astro.url.pathname const { currentLang, isHome, isPost, isTag, isAbout, getLocalizedPath } diff --git a/src/components/PostList.astro b/src/components/PostList.astro index 51cf545..0eec1c7 100644 --- a/src/components/PostList.astro +++ b/src/components/PostList.astro @@ -48,7 +48,7 @@ function getPostPath(post: Post) { {/* mobile post time */}
{/* desktop post time */} -
+
part === 'posts') + 1 -// if (slugIndex > 0 && pathParts.length > slugIndex) { -// currentPostSlug = pathParts[slugIndex] - -// // 获取所有文章 -// const posts = await getCollection('posts') - -// // 找到所有具有相同abbrlink或slug的文章 -// const relatedPosts = posts.filter(post => -// post.data.abbrlink === currentPostSlug || post.slug === currentPostSlug, -// ) - -// if (relatedPosts.length > 0) { -// // 收集所有相关文章支持的语言 -// const supportedLangs = new Set() - -// relatedPosts.forEach((post) => { -// // 处理lang属性 -// if (typeof post.data.lang === 'string' && post.data.lang.trim() !== '') { -// supportedLangs.add(post.data.lang) -// } -// // 如果没有指定语言,则假定支持默认语言 -// else { -// supportedLangs.add(defaultLocale) -// } -// }) - -// // 按照固定顺序筛选出可用的语言 -// availableLangs = fixedLangOrder.filter(lang => supportedLangs.has(lang)) -// } -// } -// } -// else { -// // 非文章页面使用所有语言 -// availableLangs = fixedLangOrder -// } - -// // 当前语言 -// function getLanguageDisplayName(code: string) { -// return new Intl.DisplayNames(['en'], { type: 'language' }).of(code) || code -// } +// 直接获取下一个语言的URL +const nextUrl = getNextLangUrl(currentPath) --- - - - + diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index c682976..b892c1b 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -10,7 +10,7 @@ import LanguageSwitcher from '@/components/Widgets/LanguageSwitcher.astro' import ThemeToggle from '@/components/Widgets/ThemeToggle.astro' import themeConfig from '@/config' import Head from '@/layouts/Head.astro' -import { getPagePath } from '@/utils/path' +import { getPagePath } from '@/utils/i18n/path' import '@/styles/font.css' import '@/styles/global.css' diff --git a/src/utils/i18n/lang.ts b/src/utils/i18n/lang.ts new file mode 100644 index 0000000..40eae16 --- /dev/null +++ b/src/utils/i18n/lang.ts @@ -0,0 +1,106 @@ +import { themeConfig } from '@/config' + +/** + * 获取下一个语言代码 + * @param currentLang 当前语言代码 + * @returns 下一个语言代码 + */ +export function getNextLang(currentLang: string): string { + // 获取默认语言和所有支持的语言 + const defaultLocale = themeConfig.global.locale + const allLocales = [defaultLocale, ...themeConfig.global.moreLocale] + + // 找到当前语言在列表中的索引 + const currentIndex = allLocales.indexOf(currentLang) + + // 如果当前语言不在列表中,返回默认语言 + if (currentIndex === -1) { + return defaultLocale + } + + // 计算下一个语言的索引(循环) + const nextIndex = (currentIndex + 1) % allLocales.length + + // 返回下一个语言代码 + return allLocales[nextIndex] +} + +/** + * 构建下一个语言的URL + * @param currentPath 当前页面路径 + * @param currentLang 当前语言代码 + * @param nextLang 下一个语言代码 + * @returns 下一个语言的URL + */ +export function buildNextLangUrl(currentPath: string, currentLang: string, nextLang: string): string { + const defaultLocale = themeConfig.global.locale + let nextUrl = '' + + if (nextLang === defaultLocale) { + // 如果下一个是默认语言,移除语言代码 + nextUrl = currentPath.replace(`/${currentLang}`, '') || '/' + } + else { + // 如果当前是默认语言(没有语言代码在路径中) + if (currentLang === defaultLocale) { + // 在路径前添加新的语言代码 + nextUrl = `/${nextLang}${currentPath}` + } + else { + // 替换当前语言代码为新的语言代码 + nextUrl = currentPath.replace(`/${currentLang}`, `/${nextLang}`) + } + } + + // 确保URL格式正确 + if (nextUrl === '') + nextUrl = '/' + + // 确保非根路径的URL末尾有斜杠 + if (nextUrl !== '/' && !nextUrl.endsWith('/')) { + nextUrl = `${nextUrl}/` + } + + return nextUrl +} + +/** + * 从当前路径中提取语言代码 + * @param currentPath 当前页面路径 + * @returns 当前语言代码 + */ +export function getLangFromPath(currentPath: string): string { + const defaultLocale = themeConfig.global.locale + let currentLang = '' + + // 检查路径是否以/xx/开始,其中xx是支持的语言代码 + for (const lang of themeConfig.global.moreLocale) { + if (currentPath.startsWith(`/${lang}/`) || currentPath === `/${lang}`) { + currentLang = lang + break + } + } + + // 如果没有找到语言代码,则认为是默认语言 + if (!currentLang) { + currentLang = defaultLocale + } + + return currentLang +} + +/** + * 直接从当前路径获取下一个语言的URL + * @param currentPath 当前页面路径 + * @returns 下一个语言的URL + */ +export function getNextLangUrl(currentPath: string): string { + // 从路径提取当前语言 + const currentLang = getLangFromPath(currentPath) + + // 获取下一个语言 + const nextLang = getNextLang(currentLang) + + // 构建下一个语言的URL + return buildNextLangUrl(currentPath, currentLang, nextLang) +} diff --git a/src/utils/path.ts b/src/utils/i18n/path.ts similarity index 100% rename from src/utils/path.ts rename to src/utils/i18n/path.ts