mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-16 03:32:51 +02:00
feat: i18n rss url and different excerpt length for different languages
This commit is contained in:
parent
e4c61bf21b
commit
f34b0cb46b
6 changed files with 62 additions and 13 deletions
|
@ -1,7 +1,8 @@
|
|||
---
|
||||
import LanguageSwitcher from '@/components/Widgets/LanguageSwitcher.astro'
|
||||
import ThemeToggle from '@/components/Widgets/ThemeToggle.astro'
|
||||
import themeConfig from '@/config'
|
||||
import { defaultLocale, themeConfig } from '@/config'
|
||||
import { getLangFromPath } from '@/i18n/lang'
|
||||
|
||||
interface Props {
|
||||
class?: string
|
||||
|
@ -10,7 +11,19 @@ interface Props {
|
|||
|
||||
const { class: className, supportedLangs = [] } = Astro.props
|
||||
const { author } = themeConfig.site
|
||||
const { links, startYear } = themeConfig.footer
|
||||
const { links: configLinks, startYear } = themeConfig.footer
|
||||
|
||||
// i18n rss path
|
||||
const currentLang = getLangFromPath(Astro.url.pathname)
|
||||
const links = configLinks.map((link) => {
|
||||
if (link.name === 'RSS') {
|
||||
return {
|
||||
...link,
|
||||
url: currentLang === defaultLocale ? link.url : `/${currentLang}${link.url}/`,
|
||||
}
|
||||
}
|
||||
return link
|
||||
})
|
||||
|
||||
const currentYear = new Date().getFullYear()
|
||||
const year = Number(startYear) === currentYear
|
||||
|
|
|
@ -68,7 +68,7 @@ function getPostPath(post: Post) {
|
|||
class="heti hidden"
|
||||
lg="mt-2 block"
|
||||
>
|
||||
<p>{generateDescription(post)}</p>
|
||||
<p>{generateDescription(post, 'list')}</p>
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
|
|
@ -4,13 +4,13 @@ export const themeConfig: ThemeConfig = {
|
|||
// SITE INFORMATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START
|
||||
site: {
|
||||
// site title
|
||||
title: 'Retypeset',
|
||||
title: '重新编排',
|
||||
// site subtitle
|
||||
subtitle: 'Revive the beauty of typography',
|
||||
subtitle: '再现版式之美',
|
||||
// use i18n title/subtitle from src/i18n/ui.ts instead of static ones above
|
||||
i18nTitle: true,
|
||||
// site description
|
||||
description: 'Retypeset is a static blog theme based on the Astro framework, inspired by Typography. Retypeset establishes a new visual standard and reimagines the layout of all pages, offering a reading experience similar to paper books, reviving the beauty of typography. Details in every sight, elegance in every space.',
|
||||
description: 'Retypeset 是一款基于Astro框架的静态博客主题,设计灵感来自Typography。本主题通过建立全新的视觉规范,对所有页面进行重新编排,打造纸质书页般的阅读体验,再现版式之美。所见皆为细节,方寸尽显优雅。',
|
||||
// author name
|
||||
author: 'radishzz',
|
||||
// site url
|
||||
|
|
|
@ -98,7 +98,7 @@ export async function getStaticPaths() {
|
|||
}
|
||||
|
||||
const { post, lang, supportedLangs } = Astro.props
|
||||
const description = generateDescription(post)
|
||||
const description = generateDescription(post, 'meta')
|
||||
const { Content, remarkPluginFrontmatter } = await post.render()
|
||||
|
||||
// 构建标签链接
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import type { CollectionEntry } from 'astro:content'
|
||||
import { generateDescription } from '@/utils/description'
|
||||
import { OGImageRoute } from 'astro-og-canvas'
|
||||
import { getCollection } from 'astro:content'
|
||||
|
@ -7,11 +8,11 @@ const blogEntries = await getCollection('posts')
|
|||
|
||||
// Convert to page data objects
|
||||
const pages = Object.fromEntries(
|
||||
blogEntries.map(post => [
|
||||
blogEntries.map((post: CollectionEntry<'posts'>) => [
|
||||
post.slug,
|
||||
{
|
||||
title: post.data.title,
|
||||
description: post.data.description || generateDescription(post),
|
||||
description: post.data.description || generateDescription(post, 'og'),
|
||||
},
|
||||
]),
|
||||
)
|
||||
|
|
|
@ -1,14 +1,46 @@
|
|||
import type { CollectionEntry } from 'astro:content'
|
||||
import { defaultLocale } from '@/config'
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import sanitizeHtml from 'sanitize-html'
|
||||
|
||||
const parser = new MarkdownIt()
|
||||
|
||||
type ExcerptScene = 'list' | 'meta' | 'og'
|
||||
|
||||
// Excerpt length in different scenarios
|
||||
const EXCERPT_LENGTHS: Record<ExcerptScene, {
|
||||
cjk: number
|
||||
other: number
|
||||
}> = {
|
||||
list: {
|
||||
cjk: 120,
|
||||
other: 240,
|
||||
},
|
||||
meta: {
|
||||
cjk: 120,
|
||||
other: 240,
|
||||
},
|
||||
og: {
|
||||
cjk: 75,
|
||||
other: 150,
|
||||
},
|
||||
}
|
||||
|
||||
const isCJKLang = (lang: string) => ['zh', 'zh-tw', 'ja'].includes(lang)
|
||||
|
||||
// Generate an excerpt from Markdown content
|
||||
export function generateExcerpt(content: string, length: number = 98): string {
|
||||
export function generateExcerpt(
|
||||
content: string,
|
||||
scene: ExcerptScene,
|
||||
lang: string,
|
||||
): string {
|
||||
if (!content)
|
||||
return ''
|
||||
|
||||
const length = isCJKLang(lang)
|
||||
? EXCERPT_LENGTHS[scene].cjk
|
||||
: EXCERPT_LENGTHS[scene].other
|
||||
|
||||
// Convert Markdown to plain text
|
||||
const plainText = sanitizeHtml(parser.render(content), {
|
||||
allowedTags: [],
|
||||
|
@ -23,11 +55,14 @@ export function generateExcerpt(content: string, length: number = 98): string {
|
|||
}
|
||||
|
||||
// Automatically generate a description for the article
|
||||
export function generateDescription(post: CollectionEntry<'posts'>): string {
|
||||
export function generateDescription(
|
||||
post: CollectionEntry<'posts'>,
|
||||
scene: ExcerptScene,
|
||||
): string {
|
||||
// If the article already has a description, return it directly
|
||||
if (post.data.description)
|
||||
return post.data.description
|
||||
|
||||
// Otherwise, generate an excerpt from the article content as the description
|
||||
return generateExcerpt(post.body)
|
||||
const lang = post.data.lang ?? defaultLocale
|
||||
return generateExcerpt(post.body, scene, lang)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue