mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-16 03:32:51 +02:00
refactor: optimize multilingual article routing logic, modify slug to abbrlink
This commit is contained in:
parent
16491dae50
commit
e5165dd740
16 changed files with 673 additions and 133 deletions
|
@ -25,7 +25,7 @@ export async function checkSlugDuplication(posts: Post[]): Promise<string[]> {
|
|||
|
||||
posts.forEach((post) => {
|
||||
const lang = post.data.lang || ''
|
||||
const slug = post.data.slug || post.slug
|
||||
const slug = post.data.abbrlink || post.slug
|
||||
|
||||
if (!slugMap.has(lang)) {
|
||||
slugMap.set(lang, new Set())
|
||||
|
|
|
@ -20,7 +20,14 @@ export function getLangFromPath(path: string) {
|
|||
export function getLocalizedPath(path: string, currentLang?: string) {
|
||||
const clean = cleanPath(path)
|
||||
const lang = currentLang || getLangFromPath(path)
|
||||
return lang === defaultLocale ? `/${clean}` : `/${lang}/${clean}`
|
||||
|
||||
// 如果是根目录(clean为空),则返回/
|
||||
if (clean === '') {
|
||||
return lang === defaultLocale ? '/' : `/${lang}/`
|
||||
}
|
||||
|
||||
// 其他路径正常处理
|
||||
return lang === defaultLocale ? `/${clean}/` : `/${lang}/${clean}/`
|
||||
}
|
||||
|
||||
export function isHomePage(path: string) {
|
||||
|
@ -55,3 +62,27 @@ export function getPagePath(path: string) {
|
|||
getLocalizedPath: (targetPath: string) => getLocalizedPath(targetPath, currentLang),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取特定文章支持的语言列表
|
||||
* @param post 文章对象
|
||||
* @returns 该文章支持的语言数组,如果未指定则返回所有配置语言
|
||||
*/
|
||||
export function getAvailableLanguages(post?: { data?: { lang?: string } }) {
|
||||
// 默认支持所有配置的语言
|
||||
const defaultLangs = ['', ...themeConfig.global.moreLocale]
|
||||
|
||||
// 如果没有提供文章对象,返回所有语言
|
||||
if (!post || !post.data) {
|
||||
return defaultLangs
|
||||
}
|
||||
|
||||
// 确定文章支持的语言
|
||||
if (post.data.lang && typeof post.data.lang === 'string' && post.data.lang.trim() !== '') {
|
||||
// 如果lang是字符串
|
||||
return ['', post.data.lang]
|
||||
}
|
||||
|
||||
// 如果没有指定或格式不对,返回所有语言
|
||||
return defaultLangs
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import type { CollectionEntry } from 'astro:content'
|
||||
import { themeConfig } from '@/config'
|
||||
|
||||
// 获取默认语言
|
||||
const defaultLocale = themeConfig.global.locale
|
||||
|
||||
export function generateLanguagePaths() {
|
||||
return themeConfig.global.moreLocale.map(lang => ({
|
||||
params: { lang },
|
||||
|
@ -10,29 +13,77 @@ export function generateLanguagePaths() {
|
|||
export function generatePostPaths(posts: CollectionEntry<'posts'>[]) {
|
||||
return posts.map(post => ({
|
||||
params: {
|
||||
slug: post.data.slug || post.slug,
|
||||
slug: post.data.abbrlink || post.slug,
|
||||
},
|
||||
props: { post },
|
||||
}))
|
||||
}
|
||||
|
||||
export function generateMultiLangPostPaths(posts: CollectionEntry<'posts'>[]) {
|
||||
return themeConfig.global.moreLocale.flatMap(lang =>
|
||||
posts.map(post => ({
|
||||
params: {
|
||||
lang,
|
||||
slug: post.data.slug || post.slug,
|
||||
},
|
||||
props: { post },
|
||||
})),
|
||||
)
|
||||
interface PathResult {
|
||||
params: {
|
||||
lang: string
|
||||
slug: string
|
||||
}
|
||||
props: {
|
||||
post: CollectionEntry<'posts'>
|
||||
}
|
||||
}
|
||||
|
||||
const result: PathResult[] = []
|
||||
|
||||
posts.forEach((post) => {
|
||||
// 确定这篇文章应该生成哪些语言版本
|
||||
let postLangs: string[] = themeConfig.global.moreLocale
|
||||
|
||||
if (post.data.lang && typeof post.data.lang === 'string' && post.data.lang.trim() !== '') {
|
||||
// 如果lang是单个字符串,转为数组
|
||||
postLangs = [post.data.lang]
|
||||
}
|
||||
|
||||
// 处理非默认语言的路径
|
||||
postLangs.forEach((lang) => {
|
||||
// 跳过默认语言,它将通过 generatePostPaths 生成
|
||||
if (lang !== defaultLocale) {
|
||||
result.push({
|
||||
params: {
|
||||
lang,
|
||||
slug: post.data.abbrlink || post.slug,
|
||||
},
|
||||
props: { post },
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// 如果文章支持默认语言,则生成无语言代码的路径
|
||||
// 默认语言条件:未指定lang属性,或lang属性等于defaultLocale
|
||||
const supportsDefaultLang = !post.data.lang
|
||||
|| (typeof post.data.lang === 'string' && post.data.lang === defaultLocale)
|
||||
|
||||
if (supportsDefaultLang) {
|
||||
// 默认语言的路径不包含语言代码,在这里用特殊参数标记
|
||||
// 这将由 [slug].astro 页面处理,不在URL中显示语言代码
|
||||
result.push({
|
||||
params: {
|
||||
lang: 'default',
|
||||
slug: post.data.abbrlink || post.slug,
|
||||
},
|
||||
props: { post },
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export function generateMultiLangTagPaths(tags: string[]) {
|
||||
return themeConfig.global.moreLocale.flatMap(lang =>
|
||||
tags.map(tag => ({
|
||||
params: { lang, tag },
|
||||
props: { tag },
|
||||
})),
|
||||
// 跳过默认语言,它将通过其他路径生成
|
||||
lang !== defaultLocale
|
||||
? tags.map(tag => ({
|
||||
params: { lang, tag },
|
||||
props: { tag },
|
||||
}))
|
||||
: [],
|
||||
)
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ export async function generateRSS({ lang }: GenerateRSSOptions = {}) {
|
|||
description: post.data.description || getExcerpt(post.body),
|
||||
// Generate absolute URL with optional language prefix
|
||||
link: new URL(
|
||||
`${lang ? `${lang}/` : ''}posts/${post.data.slug || post.slug}/`,
|
||||
`${lang ? `${lang}/` : ''}posts/${post.data.abbrlink || post.slug}/`,
|
||||
url,
|
||||
).toString(),
|
||||
// Convert markdown content to HTML, allowing img tags
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue