46 lines
1.8 KiB
TypeScript
46 lines
1.8 KiB
TypeScript
import { getLocaleByPath, getRelativeLocaleUrl } from 'astro:i18n';
|
||
import { DEFAULT_LOCALE, LOCALES, type Locale } from '@/i18n/config';
|
||
import { translate } from '@/i18n/dictionary';
|
||
|
||
/**
|
||
* 从 URL 解析语言,委托 Astro 内置的 astro:i18n.getLocaleByPath。
|
||
* 无前缀(默认语言)路径会解析回 DEFAULT_LOCALE。
|
||
*/
|
||
export function getLocaleFromUrl(url: URL | string): Locale {
|
||
const pathname = typeof url === 'string' ? url : url.pathname;
|
||
try {
|
||
const locale = getLocaleByPath(pathname);
|
||
return (LOCALES as readonly string[]).includes(locale) ? (locale as Locale) : DEFAULT_LOCALE;
|
||
} catch {
|
||
return DEFAULT_LOCALE;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 取翻译函数 t():key 即英文原文,按当前语言自动匹配翻译。
|
||
* - 英文环境:t('全部的 runway') 直接返回 '全部的 runway'(key 本身)
|
||
* - 中文环境:t('全部的 runway') 返回字典里的 '全部的 runway'(取不到则回退英文)
|
||
* - 支持 {name} 形式的插值参数。
|
||
*/
|
||
export function useTranslations(locale: Locale) {
|
||
function t(key: string, params?: Record<string, string | number>): string {
|
||
return translate(key, locale, params);
|
||
}
|
||
return { t, locale };
|
||
}
|
||
|
||
/**
|
||
* 一行取「当前语言 + 翻译函数」,干掉每个页面重复的样板:
|
||
* const { locale, t } = getI18n(Astro)
|
||
* 内部用 Astro.currentLocale(与 Layout 判断语言的方式一致),
|
||
* 取不到时回退默认语言。参数只要求含 currentLocale 字段,避免耦合 Astro 全局类型。
|
||
*/
|
||
export function getI18n(Astro: { currentLocale?: string | undefined }) {
|
||
const locale = (Astro.currentLocale as Locale) ?? DEFAULT_LOCALE;
|
||
const { t } = useTranslations(locale);
|
||
return { locale, t, getRelativeLocaleUrl };
|
||
}
|
||
|
||
export { LOCALES, DEFAULT_LOCALE };
|
||
export type { Locale };
|