mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-15 11:12:54 +02:00
refactor: update language configuration
This commit is contained in:
parent
ff59dc1a7c
commit
22dc899a95
25 changed files with 53 additions and 188 deletions
|
@ -24,7 +24,7 @@ import remarkSectionize from 'remark-sectionize'
|
|||
// Project configuration and utilities
|
||||
import UnoCSS from 'unocss/astro'
|
||||
import { themeConfig } from './src/config'
|
||||
import { langMap } from './src/i18n/ui'
|
||||
import { langMap } from './src/i18n/config'
|
||||
import { AdmonitionComponent } from './src/plugins/rehype-component-admonition'
|
||||
import { GithubCardComponent } from './src/plugins/rehype-component-github-card'
|
||||
import { parseDirectiveNode } from './src/plugins/remark-directive-rehype'
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
import { themeConfig } from '@/config'
|
||||
import { defaultLocale } from '@/i18n/config'
|
||||
import { walineLocaleMap } from '@/i18n/ui'
|
||||
import { defaultLocale, themeConfig } from '@/config'
|
||||
import { walineLocaleMap } from '@/i18n/config'
|
||||
|
||||
// Theme color configuration
|
||||
const {
|
||||
|
|
|
@ -24,7 +24,7 @@ const year = Number(startYear) === currentYear
|
|||
className,
|
||||
]}
|
||||
>
|
||||
<!-- only show on desktop -->
|
||||
<!-- Only show on desktop -->
|
||||
<div class="mb-11.5 ml-1.5 hidden gap-7 lg:flex">
|
||||
<ThemeToggle />
|
||||
<LanguageSwitcher supportedLangs={supportedLangs} />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import PostTime from '@/components/PostTime.astro'
|
||||
import { defaultLocale } from '@/i18n/config'
|
||||
import { defaultLocale } from '@/config'
|
||||
|
||||
interface Post {
|
||||
data: {
|
||||
|
@ -16,7 +16,6 @@ interface Post {
|
|||
}
|
||||
}
|
||||
|
||||
// Get post list and page language parameter from props
|
||||
const { posts, lang } = Astro.props
|
||||
|
||||
export interface Props {
|
||||
|
@ -24,9 +23,8 @@ export interface Props {
|
|||
lang?: string
|
||||
}
|
||||
|
||||
// Get multilingual post URL path
|
||||
function getPostPath(post: Post) {
|
||||
// If abbrlink is set, it will be used instead of slug
|
||||
// Prioritize abbrlink over slug
|
||||
const postPath = post.data.abbrlink || post.slug
|
||||
// Add language prefix to URL if current page is in a language subdirectory and not the default language
|
||||
return lang && lang !== defaultLocale ? `/${lang}/posts/${postPath}/` : `/posts/${postPath}/`
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<button
|
||||
id="theme-toggle"
|
||||
aria-label="Switch light/dark theme"
|
||||
class="button-theme-toggle w-4.2 uno-button"
|
||||
>
|
||||
|
|
|
@ -171,3 +171,7 @@ export const themeConfig: ThemeConfig = {
|
|||
}
|
||||
|
||||
export default themeConfig
|
||||
|
||||
export const defaultLocale = themeConfig.global.locale
|
||||
export const moreLocales = themeConfig.global.moreLocales
|
||||
export const allLocales = [defaultLocale, ...moreLocales]
|
||||
|
|
|
@ -1,5 +1,23 @@
|
|||
import { themeConfig } from '@/config'
|
||||
// Global Language Map
|
||||
export const langMap: Record<string, string[]> = {
|
||||
'zh': ['zh-CN'],
|
||||
'zh-tw': ['zh-TW'],
|
||||
'ja': ['ja-JP'],
|
||||
'en': ['en-US'],
|
||||
'es': ['es-ES'],
|
||||
'ru': ['ru-RU'],
|
||||
}
|
||||
|
||||
export const defaultLocale = themeConfig.global.locale
|
||||
export const moreLocales = themeConfig.global.moreLocales
|
||||
export const allLocales = [defaultLocale, ...moreLocales]
|
||||
// Waline Language Map
|
||||
// docs: https://waline.js.org/guide/i18n.html
|
||||
export const walineLocaleMap: Record<string, string> = {
|
||||
'zh': 'zh-CN',
|
||||
'zh-tw': 'zh-TW',
|
||||
'ja': 'jp-JP', // Waline uses jp-JP not ja-JP
|
||||
'en': 'en-US',
|
||||
'es': 'es-ES',
|
||||
'ru': 'ru-RU',
|
||||
}
|
||||
|
||||
// Supported Languages
|
||||
export const supportedLangs = Object.keys(langMap).flat()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { allLocales, defaultLocale, moreLocales } from '@/i18n/config'
|
||||
import { allLocales, defaultLocale, moreLocales } from '@/config'
|
||||
|
||||
// Gets the language code from the current path
|
||||
export function getLangFromPath(path: string) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { defaultLocale } from '@/i18n/config'
|
||||
import { defaultLocale } from '@/config'
|
||||
import { getLangFromPath, getNextLang } from '@/i18n/lang'
|
||||
import { cleanPath } from '@/utils/page'
|
||||
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
import type { CollectionEntry } from 'astro:content'
|
||||
import { allLocales, defaultLocale, moreLocales } from '@/i18n/config'
|
||||
|
||||
// 生成默认语言标签页面的路由配置
|
||||
export function getTagRoutes(tags: string[]) {
|
||||
return tags.map(tag => ({
|
||||
params: { tag },
|
||||
props: { tag },
|
||||
}))
|
||||
}
|
||||
|
||||
// 生成默认语言文章页面的路由配置
|
||||
export function getPostRoutes(posts: CollectionEntry<'posts'>[]) {
|
||||
// 创建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)
|
||||
}
|
||||
})
|
||||
|
||||
return posts.map(post => ({
|
||||
params: {
|
||||
slug: post.data.abbrlink || post.slug,
|
||||
},
|
||||
props: {
|
||||
post,
|
||||
supportedLangs: slugToLangs[post.data.abbrlink || post.slug] || [],
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
// 生成更多语言静态路由
|
||||
export function getMultiLangRoutes() {
|
||||
return moreLocales.map(lang => ({
|
||||
params: { lang },
|
||||
}))
|
||||
}
|
||||
|
||||
// 生成更多语言标签页面的路由配置
|
||||
export function getMultiLangTagRoutes(tags: string[]) {
|
||||
return moreLocales.flatMap(lang => (
|
||||
tags.map(tag => ({
|
||||
params: { lang, tag },
|
||||
props: { tag },
|
||||
}))
|
||||
))
|
||||
}
|
||||
|
||||
// 生成更多语言文章页面的路由配置
|
||||
export function getMultiLangPostRoutes(posts: CollectionEntry<'posts'>[]) {
|
||||
// 创建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)
|
||||
}
|
||||
})
|
||||
|
||||
interface PathResult {
|
||||
params: {
|
||||
lang: string
|
||||
slug: string
|
||||
}
|
||||
props: {
|
||||
post: CollectionEntry<'posts'>
|
||||
supportedLangs: string[]
|
||||
}
|
||||
}
|
||||
|
||||
return posts.flatMap((post) => {
|
||||
const result: PathResult[] = []
|
||||
const slug = post.data.abbrlink || post.slug
|
||||
|
||||
// 确定文章的语言支持
|
||||
const postLang = post.data.lang && typeof post.data.lang === 'string' && post.data.lang.trim() !== ''
|
||||
? [post.data.lang]
|
||||
: moreLocales
|
||||
|
||||
// 获取这篇文章支持的所有语言
|
||||
const supportedLangs = slugToLangs[slug] || []
|
||||
|
||||
// 添加非默认语言路径
|
||||
postLang.forEach((lang) => {
|
||||
if (lang !== defaultLocale) {
|
||||
result.push({
|
||||
params: { lang, slug },
|
||||
props: { post, supportedLangs },
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
})
|
||||
}
|
|
@ -1,27 +1,3 @@
|
|||
// Global Language Map
|
||||
export const langMap: Record<string, string[]> = {
|
||||
'zh': ['zh-CN'],
|
||||
'zh-tw': ['zh-TW'],
|
||||
'ja': ['ja-JP'],
|
||||
'en': ['en-US'],
|
||||
'es': ['es-ES'],
|
||||
'ru': ['ru-RU'],
|
||||
}
|
||||
|
||||
// Waline Language Map
|
||||
// docs: https://waline.js.org/guide/i18n.html
|
||||
export const walineLocaleMap: Record<string, string> = {
|
||||
'zh': 'zh-CN',
|
||||
'zh-tw': 'zh-TW',
|
||||
'ja': 'jp-JP', // Waline uses jp-JP not ja-JP
|
||||
'en': 'en-US',
|
||||
'es': 'es-ES',
|
||||
'ru': 'ru-RU',
|
||||
}
|
||||
|
||||
// Supported Languages
|
||||
export const supportedLangs = Object.keys(langMap).flat()
|
||||
|
||||
export const ui = {
|
||||
'zh': {
|
||||
posts: '文章',
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
import themeConfig from '@/config'
|
||||
import { allLocales, defaultLocale } from '@/i18n/config'
|
||||
import { allLocales, defaultLocale, themeConfig } from '@/config'
|
||||
import { ClientRouter } from 'astro:transitions'
|
||||
|
||||
interface Props {
|
||||
|
|
|
@ -80,7 +80,7 @@ const footerMarginClass = isPost && themeConfig.comment?.waline?.serverURL
|
|||
<ThemeToggle />
|
||||
</div>
|
||||
|
||||
<!--=============================================== Theme Toggle ===============================================-->
|
||||
<!-- Theme toggle >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
||||
<script define:vars={{ lightMode, darkMode }}>
|
||||
// Update theme
|
||||
function updateTheme() {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
---
|
||||
import { allLocales, defaultLocale } from '@/i18n/config'
|
||||
import { allLocales, defaultLocale } from '@/config'
|
||||
import Layout from '@/layouts/Layout.astro'
|
||||
|
||||
export async function getStaticPaths() {
|
||||
// 定义路径数组的类型
|
||||
type PathItem = {
|
||||
params: { about: string }
|
||||
props: { lang: string }
|
||||
|
@ -11,13 +10,13 @@ export async function getStaticPaths() {
|
|||
|
||||
const paths: PathItem[] = []
|
||||
|
||||
// 默认语言的关于页面
|
||||
// Default locale
|
||||
paths.push({
|
||||
params: { about: 'about' },
|
||||
props: { lang: defaultLocale },
|
||||
})
|
||||
|
||||
// 更多语言的关于页面
|
||||
// More locales
|
||||
allLocales.forEach((lang: string) => {
|
||||
if (lang !== defaultLocale) {
|
||||
paths.push({
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import PostList from '@/components/PostList.astro'
|
||||
import { allLocales, defaultLocale } from '@/i18n/config'
|
||||
import { allLocales, defaultLocale } from '@/config'
|
||||
import Layout from '@/layouts/Layout.astro'
|
||||
import { getPinnedPosts, getPostsByYear } from '@/utils/content'
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
import Comments from '@/components/Comments/index.astro'
|
||||
import PostTime from '@/components/PostTime.astro'
|
||||
import { allLocales, defaultLocale } from '@/i18n/config'
|
||||
import { allLocales, defaultLocale } from '@/config'
|
||||
import Layout from '@/layouts/Layout.astro'
|
||||
import { checkSlugDuplication } from '@/utils/content'
|
||||
import { generateDescription } from '@/utils/description'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
import { allLocales, defaultLocale } from '@/i18n/config'
|
||||
import { allLocales, defaultLocale } from '@/config'
|
||||
import Layout from '@/layouts/Layout.astro'
|
||||
import { getAllTags } from '@/utils/content'
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
import PostList from '@/components/PostList.astro'
|
||||
import { allLocales, defaultLocale } from '@/i18n/config'
|
||||
import { allLocales, defaultLocale } from '@/config'
|
||||
import Layout from '@/layouts/Layout.astro'
|
||||
import { getAllTags, getPostsByTag } from '@/utils/content'
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { APIContext } from 'astro'
|
||||
import { moreLocales } from '@/i18n/config'
|
||||
import { moreLocales } from '@/config'
|
||||
import { generateRSS } from '@/utils/rss'
|
||||
|
||||
// Generate static paths for all supported languages
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { APIContext } from 'astro'
|
||||
import { moreLocales } from '@/i18n/config'
|
||||
import { moreLocales } from '@/config'
|
||||
import { generateRSS } from '@/utils/rss'
|
||||
|
||||
// Generate static paths for all supported languages
|
||||
|
|
2
src/types/index.d.ts
vendored
2
src/types/index.d.ts
vendored
|
@ -1,4 +1,4 @@
|
|||
import type { supportedLangs } from '@/i18n/ui'
|
||||
import type { supportedLangs } from '@/i18n/config'
|
||||
|
||||
type Exclude<T, U> = T extends U ? never : T
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import type { CollectionEntry } from 'astro:content'
|
||||
import themeConfig from '@/config'
|
||||
import { supportedLangs } from '@/i18n/ui'
|
||||
import { supportedLangs } from '@/i18n/config'
|
||||
import { getCollection } from 'astro:content'
|
||||
|
||||
// Type definitions
|
||||
|
|
|
@ -19,8 +19,7 @@ export function generateExcerpt(content: string, length: number = 98): string {
|
|||
const normalizedText = plainText.replace(/\s+/g, ' ')
|
||||
const excerpt = normalizedText.slice(0, length).trim()
|
||||
// Add ellipsis if text was truncated
|
||||
const needsEllipsis = normalizedText.length > length
|
||||
return needsEllipsis ? `${excerpt}...` : excerpt
|
||||
return normalizedText.length > length ? `${excerpt}...` : excerpt
|
||||
}
|
||||
|
||||
// Automatically generate a description for the article
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { moreLocales } from '@/i18n/config'
|
||||
import { moreLocales } from '@/config'
|
||||
import { getLangFromPath } from '@/i18n/lang'
|
||||
import { getLocalizedPath } from '@/i18n/path'
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import type { CollectionEntry } from 'astro:content'
|
||||
import themeConfig from '@/config'
|
||||
import { defaultLocale } from '@/i18n/config'
|
||||
import themeConfig, { defaultLocale } from '@/config'
|
||||
import rss from '@astrojs/rss'
|
||||
import { getCollection } from 'astro:content'
|
||||
import MarkdownIt from 'markdown-it'
|
||||
|
@ -10,7 +9,7 @@ const parser = new MarkdownIt()
|
|||
const { title, description, url } = themeConfig.site
|
||||
const followConfig = themeConfig.seo?.follow
|
||||
|
||||
// Returns first 50 chars with proper truncation
|
||||
// Returns first 98 chars with proper truncation
|
||||
function getExcerpt(content: string): string {
|
||||
if (!content)
|
||||
return ''
|
||||
|
@ -19,8 +18,8 @@ function getExcerpt(content: string): string {
|
|||
allowedTags: [],
|
||||
allowedAttributes: {},
|
||||
})
|
||||
const excerpt = plainText.slice(0, 50).trim()
|
||||
return excerpt.length === 50 ? `${excerpt}...` : excerpt
|
||||
const excerpt = plainText.slice(0, 98).trim()
|
||||
return excerpt.length === 98 ? `${excerpt}...` : excerpt
|
||||
}
|
||||
|
||||
interface GenerateRSSOptions {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue