feat(theme-yun): support banner i18n & fix seo description, close #571

This commit is contained in:
YunYouJun 2025-07-13 22:20:22 +08:00
parent 12f82fbfd7
commit ce1fa9684b
7 changed files with 28 additions and 12 deletions

View File

@ -10,7 +10,11 @@ export default defineThemeConfig({
banner: {
enable: true,
title: '云游君的小站',
// title: '云游君的小站',
title: {
'zh-CN': '云游君的小站',
'en': ['Yun', 'You', 'Jun', 'Site'],
},
siteNameClass: 'bg-gradient-to-r gradient-text from-#1e3c72 to-dark dark:from-#66a6ff dark:to-blue-500',
},

View File

@ -17,7 +17,7 @@ const themeConfig = useThemeConfig()
// height of top/bottom line
const { totalCharHeight, chars } = useYunBanner(themeConfig.value.banner)
const { totalCharHeight, chars, bannerTitle } = useYunBanner(themeConfig.value.banner)
const bannerStyles = computed<CSSProperties>(() => {
const styles: CSSProperties = {
@ -64,13 +64,13 @@ onMounted(async () => {
<template v-if="yun.isNimbo">
<YunBannerCharContainer
v-if="animationStatus === 'banner'"
:title="themeConfig.banner.title"
:title="bannerTitle"
:chars="chars"
/>
</template>
<template v-if="yun.isStrato">
<YunBannerCharContainer
:title="themeConfig.banner.title"
:title="bannerTitle"
:chars="chars"
/>
</template>

View File

@ -1,11 +1,19 @@
import type { YunTheme } from '../types'
import { random } from 'valaxy'
import { random, useValaxyI18n } from 'valaxy'
import { computed } from 'vue'
export function useYunBanner(options: YunTheme.Banner) {
const { $tO } = useValaxyI18n()
const bannerTitle = computed(() => {
if (Array.isArray(options.title)) {
return options.title
}
return $tO<string | string[]>(options.title)
})
const chars = computed(() => {
const arr = []
for (let i = 0; i < options.title.length; i++) {
for (let i = 0; i < bannerTitle.value.length; i++) {
const rn = random(1.5, 3.5)
arr.push(rn)
}
@ -15,6 +23,7 @@ export function useYunBanner(options: YunTheme.Banner) {
const totalCharHeight = computed(() => chars.value.reduce((a, b) => a + b, 0))
return {
bannerTitle,
chars,
totalCharHeight,
}

View File

@ -12,8 +12,11 @@ export namespace YunTheme {
/**
* @en Banner title
* @zh ['Hello', 'World']
*
* i18n: { 'en': 'Title', 'zh-CN': '标题' }
* { en: ['Hello', 'World'], 'zh-CN': ['你好', '世界'] }
*/
title: string | string[]
title: string | string[] | Record<string, string | string[]>
/**
*

View File

@ -26,15 +26,15 @@ export function useValaxyApp() {
// seo
// todo: get first image url from markdown
const siteUrl = computed(() => fm.value.url || siteConfig.value.url)
const description = computed(() => fm.value.excerpt || fm.value.description || siteConfig.value.description)
const description = computed(() => $tO(fm.value.excerpt) || $tO(fm.value.description) || $tO(siteConfig.value.description))
useSeoMeta({
description,
ogDescription: description,
ogLocale: computed(() => locale.value || fm.value.lang || siteConfig.value.lang || 'en'),
ogLocaleAlternate: computed(() => siteConfig.value.languages.filter(l => l !== locale.value)),
ogSiteName: computed(() => siteConfig.value.title),
ogTitle: computed(() => $tO(fm.value.title || siteConfig.value.title)),
ogSiteName: computed(() => $t(siteConfig.value.title)),
ogTitle: computed(() => $tO(fm.value.title) || $t(siteConfig.value.title)),
ogImage: computed(() => fm.value.ogImage || fm.value.cover || siteConfig.value.favicon),
ogType: 'website',
ogUrl: siteUrl,

View File

@ -92,7 +92,7 @@ export function useValaxyI18n() {
* "en": "Hello"
* }
*/
const $tO = (data?: string | Record<string, string>) => {
const $tO = <T = string>(data?: string | Record<string, T>) => {
return tObject(data || '', locale.value)
}

View File

@ -9,7 +9,7 @@
* tObject({ 'en': 'English', 'zh-CN': '中文' }, 'fr') // English
* ```
*/
export function tObject(data: string | Record<string, string>, lang: string): string {
export function tObject<T = string>(data: string | Record<string, T>, lang: string): T | string {
if (typeof data === 'object') {
return data[lang] || Object.values(data)[0] || ''
}