From d352b6fb65d4e23ccc701dbd80dbc9fef842bd17 Mon Sep 17 00:00:00 2001 From: radishzzz Date: Fri, 14 Mar 2025 16:18:17 +0000 Subject: [PATCH] refactor: organize and categorize functions --- src/components/MainHeader.astro | 2 +- src/components/MobileHeader.astro | 2 +- src/components/Navbar.astro | 2 +- src/components/PostTime.astro | 2 +- src/components/Widgets/LanguageSwitcher.astro | 4 +- src/i18n/lang.ts | 123 ++--------------- src/i18n/path.ts | 130 ++++++++++++------ src/i18n/ui.ts | 8 +- src/layouts/Layout.astro | 2 +- src/pages/[lang]/tags/[tag].astro | 2 +- src/types/index.d.ts | 6 +- src/utils/content.ts | 4 +- src/utils/page.ts | 39 ++++++ 13 files changed, 150 insertions(+), 176 deletions(-) create mode 100644 src/utils/page.ts diff --git a/src/components/MainHeader.astro b/src/components/MainHeader.astro index 9298a7b..25262a3 100644 --- a/src/components/MainHeader.astro +++ b/src/components/MainHeader.astro @@ -1,6 +1,6 @@ --- import themeConfig from '@/config' -import { getPageInfo } from '@/i18n/path' +import { getPageInfo } from '@/utils/page' const { title, subtitle } = themeConfig.site const { titleSpace } = themeConfig.global diff --git a/src/components/MobileHeader.astro b/src/components/MobileHeader.astro index c15ea82..ee50b38 100644 --- a/src/components/MobileHeader.astro +++ b/src/components/MobileHeader.astro @@ -1,6 +1,6 @@ --- import themeConfig from '@/config' -import { getPageInfo } from '@/i18n/path' +import { getPageInfo } from '@/utils/page' const { title, subtitle } = themeConfig.site const { titleSpace } = themeConfig.global diff --git a/src/components/Navbar.astro b/src/components/Navbar.astro index 10b52f9..a9b0052 100644 --- a/src/components/Navbar.astro +++ b/src/components/Navbar.astro @@ -1,6 +1,6 @@ --- -import { getPageInfo } from '@/i18n/path' import { ui } from '@/i18n/ui' +import { getPageInfo } from '@/utils/page' const { currentLang, isHome, isPost, isTag, isAbout, getLocalizedPath } = getPageInfo(Astro.url.pathname) diff --git a/src/components/PostTime.astro b/src/components/PostTime.astro index 3198d0b..75d70de 100644 --- a/src/components/PostTime.astro +++ b/src/components/PostTime.astro @@ -1,6 +1,6 @@ --- import { themeConfig } from '@/config' -import { isPostPage } from '@/i18n/path' +import { isPostPage } from '@/utils/page' interface Props { date: Date diff --git a/src/components/Widgets/LanguageSwitcher.astro b/src/components/Widgets/LanguageSwitcher.astro index 11ccb5b..27e7836 100644 --- a/src/components/Widgets/LanguageSwitcher.astro +++ b/src/components/Widgets/LanguageSwitcher.astro @@ -1,6 +1,6 @@ --- -import { getNextLangUrl, getPostNextLangUrl } from '@/i18n/lang' -import { isPostPage } from '@/i18n/path' +import { getNextLangUrl, getPostNextLangUrl } from '@/i18n/path' +import { isPostPage } from '@/utils/page' interface Props { supportedLangs: string[] diff --git a/src/i18n/lang.ts b/src/i18n/lang.ts index 92e9d55..1d82609 100644 --- a/src/i18n/lang.ts +++ b/src/i18n/lang.ts @@ -1,5 +1,13 @@ import { allLocales, defaultLocale, moreLocales } from '@/i18n/config' -import { walineLocaleMap } from '@/i18n/ui' + +// Gets the language code from the current path +export function getLangFromPath(path: string) { + const secondaryLang = moreLocales.find( + lang => + path.startsWith(`/${lang}/`), + ) + return secondaryLang || defaultLocale +} /** * 获取下一个语言代码 @@ -25,70 +33,6 @@ export function getNextLang(currentLang: string): string { return allLocales[nextIndex] } -/** - * 构建下一个语言的URL - * @param currentPath 当前页面路径 - * @param currentLang 当前语言代码 - * @param nextLang 下一个语言代码 - * @returns 下一个语言的URL - */ -export function buildNextLangUrl(currentPath: string, currentLang: string, nextLang: string): string { - // 直接使用导入的变量 - 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 { - // 直接使用导入的变量 - let currentLang = '' - - // 检查路径是否以/xx/开始,其中xx是支持的语言代码 - for (const lang of moreLocales) { - if (currentPath.startsWith(`/${lang}/`) || currentPath === `/${lang}`) { - currentLang = lang - break - } - } - - // 如果没有找到语言代码,则认为是默认语言 - if (!currentLang) { - currentLang = defaultLocale - } - - return currentLang -} - /** * 获取文章支持的语言 * @param lang 文章的语言属性 @@ -105,52 +49,3 @@ export function getSupportedLangs(lang?: string): string[] { // 否则返回所有支持的语言 return allLocales } - -/** - * 直接从当前路径获取下一个语言的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) -} - -/** - * 根据支持的语言列表获取下一个语言的URL - * @param currentPath 当前路径 - * @param supportedLangs 文章支持的语言列表 - * @returns 下一个可用语言的URL - */ -export function getPostNextLangUrl(currentPath: string, supportedLangs: string[]): string { - // 从路径提取当前语言 - const currentLang = getLangFromPath(currentPath) - - // 如果没有提供支持的语言或列表为空,使用普通的语言切换 - if (!supportedLangs || supportedLangs.length === 0) { - return getNextLangUrl(currentPath) - } - - // 找到当前语言在支持的语言中的索引 - const currentIndex = supportedLangs.indexOf(currentLang) - - // 如果当前语言不在支持的语言中,或者路径是根路径,返回第一个支持的语言 - if (currentIndex === -1 || currentPath === '/') { - const nextLang = supportedLangs[0] - // 如果下一个语言是默认语言,返回根路径 - return nextLang === defaultLocale ? '/' : `/${nextLang}/` - } - - // 计算下一个语言的索引 - const nextIndex = (currentIndex + 1) % supportedLangs.length - const nextLang = supportedLangs[nextIndex] - - // 构建下一个语言的URL - return buildNextLangUrl(currentPath, currentLang, nextLang) -} diff --git a/src/i18n/path.ts b/src/i18n/path.ts index 696f266..ee63eb9 100644 --- a/src/i18n/path.ts +++ b/src/i18n/path.ts @@ -1,18 +1,6 @@ -import { defaultLocale, moreLocales } from '@/i18n/config' - -// Removes leading and trailing slashes from a path -export function cleanPath(path: string) { - return path.replace(/^\/|\/$/g, '') -} - -// Gets the language code from the current path -export function getLangFromPath(path: string) { - const secondaryLang = moreLocales.find( - lang => - path.startsWith(`/${lang}/`), - ) - return secondaryLang || defaultLocale -} +import { defaultLocale } from '@/i18n/config' +import { getLangFromPath, getNextLang } from '@/i18n/lang' +import { cleanPath } from '@/utils/page' // Generates a localized path based on current language export function getLocalizedPath(path: string, currentLang?: string) { @@ -26,34 +14,90 @@ export function getLocalizedPath(path: string, currentLang?: string) { return lang === defaultLocale ? `/${clean}/` : `/${lang}/${clean}/` } -// Checks if the current path is the home/post/tag/about page -export function isHomePage(path: string) { - const clean = cleanPath(path) - return clean === '' || moreLocales.includes(clean) -} -export function isPostPage(path: string) { - const clean = cleanPath(path) - return clean.startsWith('posts') || moreLocales.some(lang => clean.startsWith(`${lang}/posts`)) -} -export function isTagPage(path: string) { - const clean = cleanPath(path) - return clean.startsWith('tags') || moreLocales.some(lang => clean.startsWith(`${lang}/tags`)) -} -export function isAboutPage(path: string) { - const clean = cleanPath(path) - return clean.startsWith('about') || moreLocales.some(lang => clean.startsWith(`${lang}/about`)) -} +/** + * 构建下一个语言的URL + * @param currentPath 当前页面路径 + * @param currentLang 当前语言代码 + * @param nextLang 下一个语言代码 + * @returns 下一个语言的URL + */ +export function buildNextLangUrl(currentPath: string, currentLang: string, nextLang: string): string { + // 直接使用导入的变量 + let nextUrl = '' -// Returns page context including language and page type information -export function getPageInfo(path: string) { - const currentLang = getLangFromPath(path) - - return { - currentLang, - isHome: isHomePage(path), - isPost: isPostPage(path), - isTag: isTagPage(path), - isAbout: isAboutPage(path), - getLocalizedPath: (targetPath: string) => getLocalizedPath(targetPath, currentLang), + 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 +} + +/** + * 直接从当前路径获取下一个语言的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) +} + +/** + * 根据支持的语言列表获取下一个语言的URL + * @param currentPath 当前路径 + * @param supportedLangs 文章支持的语言列表 + * @returns 下一个可用语言的URL + */ +export function getPostNextLangUrl(currentPath: string, supportedLangs: string[]): string { + // 从路径提取当前语言 + const currentLang = getLangFromPath(currentPath) + + // 如果没有提供支持的语言或列表为空,使用普通的语言切换 + if (!supportedLangs || supportedLangs.length === 0) { + return getNextLangUrl(currentPath) + } + + // 找到当前语言在支持的语言中的索引 + const currentIndex = supportedLangs.indexOf(currentLang) + + // 如果当前语言不在支持的语言中,或者路径是根路径,返回第一个支持的语言 + if (currentIndex === -1 || currentPath === '/') { + const nextLang = supportedLangs[0] + // 如果下一个语言是默认语言,返回根路径 + return nextLang === defaultLocale ? '/' : `/${nextLang}/` + } + + // 计算下一个语言的索引 + const nextIndex = (currentIndex + 1) % supportedLangs.length + const nextLang = supportedLangs[nextIndex] + + // 构建下一个语言的URL + return buildNextLangUrl(currentPath, currentLang, nextLang) } diff --git a/src/i18n/ui.ts b/src/i18n/ui.ts index d5b16ea..8f93463 100644 --- a/src/i18n/ui.ts +++ b/src/i18n/ui.ts @@ -19,13 +19,9 @@ export const walineLocaleMap: Record = { 'ru': 'ru-RU', } -// Standard Language Code (Unused) -export const langCode = Object.values(langMap).flat() +// Supported Languages +export const supportedLangs = Object.keys(langMap).flat() -// Abbreviated Language Code -export const langPath = Object.keys(langMap).flat() - -// UI Translation export const ui = { 'zh': { posts: '文章', diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index c865bca..c133881 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -9,8 +9,8 @@ import LanguageSwitcher from '@/components/Widgets/LanguageSwitcher.astro' // import Scrollbar from '@/components/Scrollbar.astro' import ThemeToggle from '@/components/Widgets/ThemeToggle.astro' import themeConfig from '@/config' -import { getPageInfo } from '@/i18n/path' import Head from '@/layouts/Head.astro' +import { getPageInfo } from '@/utils/page' import '@/styles/font.css' import '@/styles/global.css' diff --git a/src/pages/[lang]/tags/[tag].astro b/src/pages/[lang]/tags/[tag].astro index 7f6c066..c0be869 100644 --- a/src/pages/[lang]/tags/[tag].astro +++ b/src/pages/[lang]/tags/[tag].astro @@ -11,7 +11,7 @@ export async function getStaticPaths() { const { lang } = Astro.params const { tag } = Astro.props -const posts = await getPostsByTag(tag) +const posts = await getPostsByTag(tag, lang) const allTags = await getAllTags() --- diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 5e46548..0a860d8 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1,4 +1,4 @@ -import type { langPath } from '@/i18n/ui' +import type { supportedLangs } from '@/i18n/ui' type Exclude = T extends U ? never : T @@ -30,8 +30,8 @@ export interface ThemeConfig { } global: { - locale: typeof langPath[number] - moreLocales: typeof langPath[number][] + locale: typeof supportedLangs[number] + moreLocales: typeof supportedLangs[number][] fontStyle: 'sans' | 'serif' dateFormat: 'YYYY-MM-DD' | 'MM-DD-YYYY' | 'DD-MM-YYYY' | 'MONTH DAY YYYY' | 'DAY MONTH YYYY' titleSpace: 1 | 2 | 3 diff --git a/src/utils/content.ts b/src/utils/content.ts index 5447e63..a1465bf 100644 --- a/src/utils/content.ts +++ b/src/utils/content.ts @@ -1,6 +1,6 @@ import type { CollectionEntry } from 'astro:content' import themeConfig from '@/config' -import { langPath } from '@/i18n/ui' +import { supportedLangs } from '@/i18n/ui' import { getCollection } from 'astro:content' // Type definitions @@ -52,7 +52,7 @@ export async function getPosts(lang?: string) { 'posts', ({ data }: Post) => { const shouldInclude = import.meta.env.DEV || !data.draft - if (!langPath.includes(currentLang)) { + if (!supportedLangs.includes(currentLang)) { return shouldInclude && data.lang === '' } return shouldInclude && (data.lang === currentLang || data.lang === '') diff --git a/src/utils/page.ts b/src/utils/page.ts new file mode 100644 index 0000000..3b901cb --- /dev/null +++ b/src/utils/page.ts @@ -0,0 +1,39 @@ +import { moreLocales } from '@/i18n/config' +import { getLangFromPath } from '@/i18n/lang' +import { getLocalizedPath } from '@/i18n/path' + +// Removes leading and trailing slashes from a path +export function cleanPath(path: string) { + return path.replace(/^\/|\/$/g, '') +} +// Checks if the current path is the home/post/tag/about page +export function isHomePage(path: string) { + const clean = cleanPath(path) + return clean === '' || moreLocales.includes(clean) +} +export function isPostPage(path: string) { + const clean = cleanPath(path) + return clean.startsWith('posts') || moreLocales.some(lang => clean.startsWith(`${lang}/posts`)) +} +export function isTagPage(path: string) { + const clean = cleanPath(path) + return clean.startsWith('tags') || moreLocales.some(lang => clean.startsWith(`${lang}/tags`)) +} +export function isAboutPage(path: string) { + const clean = cleanPath(path) + return clean.startsWith('about') || moreLocales.some(lang => clean.startsWith(`${lang}/about`)) +} + +// Returns page context including language and page type information +export function getPageInfo(path: string) { + const currentLang = getLangFromPath(path) + + return { + currentLang, + isHome: isHomePage(path), + isPost: isPostPage(path), + isTag: isTagPage(path), + isAbout: isAboutPage(path), + getLocalizedPath: (targetPath: string) => getLocalizedPath(targetPath, currentLang), + } +}