mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-04-23 10:58:13 +08:00
feat(theme): improve locales (#366)
* chore: tweak * feat(theme): improve locales
This commit is contained in:
parent
8b39248f96
commit
9906f1a4e2
@ -9,8 +9,8 @@ export const themeConfig = defineNoteConfig({
|
||||
collapsed: false,
|
||||
items: [
|
||||
'配置说明',
|
||||
'多语言配置',
|
||||
'主题配置',
|
||||
'多语言配置',
|
||||
'导航栏配置',
|
||||
'notes配置',
|
||||
'侧边栏配置',
|
||||
|
||||
@ -344,9 +344,9 @@ interface LastUpdatedOptions {
|
||||
- 默认值: `{}`
|
||||
- 详情: 多语言配置
|
||||
|
||||
多语言配置,参考 [此文档](./多语言配置.md)
|
||||
不同语言的文本配置,参考 [此文档](./多语言配置.md)
|
||||
|
||||
多语言配置支持以下 [Locale](#locale-配置) 所有配置选项
|
||||
多语言配置支持以下 [Locale](#locale-配置) 所有配置选项以控制不同语言下的主题行为。
|
||||
|
||||
## Locale 配置
|
||||
|
||||
@ -385,16 +385,6 @@ interface LastUpdatedOptions {
|
||||
|
||||
此选项注入一个内联脚本,从本地存储恢复用户设置。这确保在呈现页面之前应用 `[data-theme="dark"]` 以避免闪烁。
|
||||
|
||||
### appearanceText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Appearance'`
|
||||
- 详情: 导航栏中的主题切换按钮的文本。
|
||||
|
||||
### avatar <Badge type="danger" text="弃用" />
|
||||
|
||||
弃用,请使用 [profile](#profile)。
|
||||
|
||||
### profile
|
||||
|
||||
- 类型: `ProfileOptions`
|
||||
@ -740,66 +730,6 @@ interface SidebarItem {
|
||||
|
||||
详情请参考 [公告板](../guide/功能/公告板.md)
|
||||
|
||||
### selectLanguageName
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `''`
|
||||
- 详情:
|
||||
|
||||
Locale 的语言名称。
|
||||
|
||||
该配置项 **仅能在主题配置的 [locales](#locales) 的内部生效** 。它将被用作 locale 的语言名称,展示在 _选择语言菜单_ 内。
|
||||
|
||||
### selectLanguageText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `''`
|
||||
- 详情:
|
||||
|
||||
_选择语言菜单_ 的文本。
|
||||
|
||||
如果你在站点配置中设置了多个 [locales](#locales) ,那么 _选择语言菜单_ 就会显示在导航栏中仓库按钮的旁边。
|
||||
|
||||
### selectLanguageAriaLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `''`
|
||||
- 详情:
|
||||
|
||||
_选择语言菜单 的 `aria-label` 属性。_
|
||||
|
||||
它主要是为了站点的可访问性 (a11y) 。
|
||||
|
||||
### sidebarMenuLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Menu'`
|
||||
- 详情:
|
||||
|
||||
移动设备下的导航栏中 菜单选项的文本。
|
||||
|
||||
### returnToTopLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'return to top'`
|
||||
- 详情:
|
||||
|
||||
移动设备下的导航栏中返回顶部的文本。
|
||||
|
||||
### outlineLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'On this page'`
|
||||
- 详情:
|
||||
|
||||
移动设备下的导航栏中大纲标题的文本
|
||||
|
||||
### editLinkText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Edit this page'`
|
||||
- 详情: 编辑链接文本
|
||||
|
||||
### editLinkPattern
|
||||
|
||||
- 类型: `string`
|
||||
@ -808,36 +738,6 @@ interface SidebarItem {
|
||||
|
||||
示例: `':repo/edit/:branch/:path'`
|
||||
|
||||
### latestUpdatedText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Latest Updated'`
|
||||
- 详情: 最近更新时间 的文本
|
||||
|
||||
### contributorsText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Contributors'`
|
||||
- 详情: 贡献者的文本
|
||||
|
||||
### changelogText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Changelog'`
|
||||
- 详情: 变更记录的文本
|
||||
|
||||
### changelogOnText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'On'`
|
||||
- 详情: 单次变更记录的时间文本
|
||||
|
||||
### changelogButtonText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'View All Changelog'`
|
||||
- 详情: 变更记录的按钮文本
|
||||
|
||||
### copyright
|
||||
|
||||
- 类型: `boolean | CopyrightLicense | CopyrightOptions`
|
||||
@ -846,66 +746,18 @@ interface SidebarItem {
|
||||
|
||||
详情请参考 [版权所有](../guide/功能/文章版权所有.md)
|
||||
|
||||
### copyrightText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Copyright'`
|
||||
- 详情: 版权所有的文本
|
||||
|
||||
### copyrightAuthorText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Copyright Ownership:'`
|
||||
- 详情: 版权所有者的文本
|
||||
|
||||
### copyrightCreationOriginalText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'This article link:'`
|
||||
- 详情: 本文链接的文本
|
||||
|
||||
### copyrightCreationTranslateText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'This article translated from:'`
|
||||
- 详情: 本文翻译的文本
|
||||
|
||||
### copyrightCreationReprintText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'This article reprint from:'`
|
||||
- 详情: 本文转载的文本
|
||||
|
||||
### copyrightLicenseText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'License under:'`
|
||||
- 详情: 版权许可证的文本
|
||||
|
||||
### prevPage
|
||||
|
||||
- 类型: `boolean`
|
||||
- 默认值: `true`
|
||||
- 详情: 是否显示上一页
|
||||
|
||||
### prevPageLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Previous Page'`
|
||||
- 详情: 上一页的文本
|
||||
|
||||
### nextPage
|
||||
|
||||
- 类型: `boolean`
|
||||
- 默认值: `true`
|
||||
- 详情: 是否显示下一页
|
||||
|
||||
### nextPageLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Next Page'`
|
||||
- 详情: 下一页的文本
|
||||
|
||||
### createTime
|
||||
|
||||
- 类型: `boolean | 'only-blog'`
|
||||
@ -915,19 +767,3 @@ interface SidebarItem {
|
||||
- `false` - 不显示
|
||||
- `'only-blog'` - 只显示在博客文章页面
|
||||
- `true` - 显示在所有文章页面
|
||||
|
||||
### notFound
|
||||
|
||||
- 类型: `NotFound | undefined`
|
||||
- 默认值: `undefined`
|
||||
- 详情: 404 页面配置
|
||||
|
||||
```ts
|
||||
interface NotFound {
|
||||
code?: string
|
||||
title?: string
|
||||
quote?: string
|
||||
linkLabel?: string
|
||||
linkText?: string
|
||||
}
|
||||
```
|
||||
|
||||
@ -1,155 +1,279 @@
|
||||
---
|
||||
title: 多语言
|
||||
title: 多语言配置
|
||||
author: pengzhanbo
|
||||
createTime: 2024/03/02 10:07:15
|
||||
permalink: /config/locales/
|
||||
---
|
||||
|
||||
## 设置语言 <Badge type="danger">重要</Badge>
|
||||
这些选项用于配置与语言相关的文本。
|
||||
|
||||
你需要为每个语言设置 `lang` 选项。即使你只在使用单个语言,你也必须在 `.vuepress/config.{js,ts}` 中设置 `lang`。
|
||||
如果你的站点是以非内置语言支持以外的其他语言提供服务的,你应该为每个语言设置这些选项来提供翻译。
|
||||
|
||||
::: tip 为什么要这样做?
|
||||
要提供正确的语言环境文本,主题需要知道根文件夹以及每个多语言文件夹正在使用哪种语言。
|
||||
:::
|
||||
## 内置语言支持
|
||||
|
||||
主题内置了以下语言支持,包括:
|
||||
|
||||
- 简体中文 (`zh-CN`) - `/zh/`
|
||||
- 繁体中文 (`zh-TW`) - `/zh-tw/`
|
||||
- 英语 (`en-US`) - `/en/`
|
||||
- 法语 (`fr-FR`) - `/fr/`
|
||||
- 德语 (`de-DE`) - `/de/`
|
||||
- 俄语 (`ru-RU`) - `/ru/`
|
||||
- 日语 (`ja-JP`) - `/ja/`
|
||||
|
||||
## 配置
|
||||
|
||||
您应该将配置写入到 `theme.locales` 中。
|
||||
|
||||
您可以在 `.vuepress/config.ts` ,或者在 `.vuepress/plume.config.ts` 中进行配置:
|
||||
|
||||
::: code-tabs
|
||||
@tab 单语言
|
||||
|
||||
```ts
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
|
||||
export default defineUserConfig({
|
||||
// 设置正在使用的语言
|
||||
lang: 'zh-CN',
|
||||
})
|
||||
```
|
||||
|
||||
@tab 多语言
|
||||
|
||||
```ts
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
|
||||
export default defineUserConfig({
|
||||
locales: {
|
||||
'/': {
|
||||
// 设置正在使用的语言
|
||||
lang: 'zh-CN',
|
||||
},
|
||||
'/en/': {
|
||||
// 设置正在使用的语言
|
||||
lang: 'en-US',
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## 多语言配置
|
||||
|
||||
`locales` 是一个对象,其键为每个语言的路径前缀,值为该语言的配置,可以包含 `title`, `description`, `lang` 等。
|
||||
|
||||
你应当为每个语言设置 `lang` 选项,以便主题和插件能够正确的处理它们。
|
||||
|
||||
如果站点和主题配置中的 `locales` 对象只包含 "/" 一个键,则主题不会显示语言切换菜单。当你通过 `locales` 设置多个键,即存在多个语言的时候,我们会在导航栏显示语言切换菜单。
|
||||
|
||||
## 语言适配
|
||||
|
||||
主题默认适配了以下语言
|
||||
|
||||
- 简体中文 (zh-CN)
|
||||
- 英文(美国) (en-US)
|
||||
|
||||
::: tip
|
||||
|
||||
如果您希望支持更多语言,欢迎通过
|
||||
[PR](https://github.com/pengzhanbo/vuepress-theme-plume/pulls?q=sort%3Aupdated-desc+is%3Apr+is%3Aopen) 在 主题仓库的 `/theme/src/node/locales` 目录中按照相同的方式添加语言。
|
||||
|
||||
:::
|
||||
|
||||
## 为每个语言设置主题选项
|
||||
|
||||
与站点配置和 `@vuepress/theme-default` 的主题配置相同,`vuepress-theme-plume` 也支持你在主题选项中设置 locale 选项,并为每种语言设置不同的配置。
|
||||
|
||||
::: code-tabs
|
||||
@tab .vuepress/config.ts
|
||||
|
||||
```ts :no-line-numbers
|
||||
```ts
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
export default defineUserConfig({
|
||||
locales: {
|
||||
'/': {
|
||||
lang: 'en-US',
|
||||
},
|
||||
'/zh/': {
|
||||
lang: 'zh-CN',
|
||||
},
|
||||
},
|
||||
|
||||
theme: plumeTheme({
|
||||
// 通用配置
|
||||
// ...
|
||||
locales: {
|
||||
'/': {
|
||||
// 英文配置
|
||||
// ...
|
||||
},
|
||||
'/zh/': {
|
||||
// 中文配置
|
||||
// ...
|
||||
},
|
||||
},
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
**使用主题配置文件:**
|
||||
|
||||
::: code-tabs
|
||||
@tab .vuepress/config.ts
|
||||
|
||||
```ts
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
export default defineUserConfig({
|
||||
locales: {
|
||||
'/': {
|
||||
lang: 'en-US',
|
||||
},
|
||||
'/zh/': {
|
||||
lang: 'zh-CN',
|
||||
},
|
||||
},
|
||||
|
||||
theme: plumeTheme(),
|
||||
// 非内置语言的语言代码
|
||||
'/xxx/': {
|
||||
// 语言配置
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
@tab .vuepress/plume.config.ts
|
||||
|
||||
```ts
|
||||
import { defineThemeConfig } from 'vuepress-theme-plume'
|
||||
import { definePlumeConfig } from 'vuepress-theme-plume'
|
||||
|
||||
export default defineThemeConfig({
|
||||
// 通用配置
|
||||
// ...
|
||||
export default definePlumeConfig({
|
||||
locales: {
|
||||
'/': {
|
||||
// 英文配置
|
||||
// ...
|
||||
},
|
||||
'/zh/': {
|
||||
// 中文配置
|
||||
// ...
|
||||
},
|
||||
},
|
||||
// 非内置语言的语言代码
|
||||
'/xxx/': {
|
||||
// 语言配置
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
### appearanceText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Appearance'`
|
||||
- 详情: 导航栏中的主题切换按钮的文本。
|
||||
|
||||
### selectLanguageName
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `''`
|
||||
- 详情:
|
||||
|
||||
Locale 的语言名称。
|
||||
|
||||
该配置项 **仅能在主题配置的 [locales](./主题配置.md#locales) 的内部生效** 。它将被用作 locale 的语言名称,展示在 _选择语言菜单_ 内。
|
||||
|
||||
### selectLanguageText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `''`
|
||||
- 详情:
|
||||
|
||||
_选择语言菜单_ 的文本。
|
||||
|
||||
如果你在站点配置中设置了多个 [locales](./主题配置.md#locales) ,那么 _选择语言菜单_ 就会显示在导航栏中仓库按钮的旁边。
|
||||
|
||||
### selectLanguageAriaLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `''`
|
||||
- 详情:
|
||||
|
||||
_选择语言菜单 的 `aria-label` 属性。_
|
||||
|
||||
它主要是为了站点的可访问性 (a11y) 。
|
||||
|
||||
### homeText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Home'`
|
||||
- 详情: 主页链接的文本。
|
||||
|
||||
- 主题默认导航栏中的首页链接的文本。
|
||||
- 面包屑导航中的首页链接的文本。
|
||||
|
||||
### blogText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Blog'`
|
||||
- 详情: 博客链接的文本。
|
||||
|
||||
- 主题默认导航栏中的博客链接的文本。
|
||||
- 面包屑导航中的博客链接的文本。
|
||||
|
||||
### tagText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Tags'`
|
||||
- 详情: 标签链接的文本。
|
||||
|
||||
- 主题默认导航栏中的标签链接的文本。
|
||||
- 博客页中的标签链接的文本。
|
||||
- 博客标签页中的标题。
|
||||
|
||||
### categoryText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Categories'`
|
||||
- 详情: 分类链接的文本。
|
||||
|
||||
- 主题默认导航栏中的分类链接的文本。
|
||||
- 博客页中的分类链接的文本。
|
||||
- 博客分类页中的标题。
|
||||
|
||||
### archiveText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Archives'`
|
||||
- 详情: 归档链接的文本。
|
||||
|
||||
- 主题默认导航栏中的归档链接的文本。
|
||||
- 博客页中的归档链接的文本。
|
||||
- 博客归档页中的标题。
|
||||
|
||||
### archiveTotalText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'{count} articles'`
|
||||
- 详情: 归档页中的总文章数的文本。
|
||||
|
||||
### sidebarMenuLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Menu'`
|
||||
- 详情:
|
||||
|
||||
移动设备下的导航栏中 菜单选项的文本。
|
||||
|
||||
### returnToTopLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'return to top'`
|
||||
- 详情:
|
||||
|
||||
移动设备下的导航栏中返回顶部的文本。
|
||||
|
||||
### outlineLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'On this page'`
|
||||
- 详情:
|
||||
|
||||
移动设备下的导航栏中大纲标题的文本
|
||||
|
||||
### editLinkText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Edit this page'`
|
||||
- 详情: 编辑链接文本
|
||||
|
||||
### latestUpdatedText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Latest Updated'`
|
||||
- 详情: 最近更新时间 的文本
|
||||
|
||||
### contributorsText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Contributors'`
|
||||
- 详情: 贡献者的文本
|
||||
|
||||
### changelogText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Changelog'`
|
||||
- 详情: 变更记录的文本
|
||||
|
||||
### changelogOnText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'On'`
|
||||
- 详情: 单次变更记录的时间文本
|
||||
|
||||
### changelogButtonText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'View All Changelog'`
|
||||
- 详情: 变更记录的按钮文本
|
||||
|
||||
### copyrightText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Copyright'`
|
||||
- 详情: 版权所有的文本
|
||||
|
||||
### copyrightAuthorText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Copyright Ownership:'`
|
||||
- 详情: 版权所有者的文本
|
||||
|
||||
### copyrightCreationOriginalText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'This article link:'`
|
||||
- 详情: 本文链接的文本
|
||||
|
||||
### copyrightCreationTranslateText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'This article translated from:'`
|
||||
- 详情: 本文翻译的文本
|
||||
|
||||
### copyrightCreationReprintText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'This article reprint from:'`
|
||||
- 详情: 本文转载的文本
|
||||
|
||||
### copyrightLicenseText
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'License under:'`
|
||||
- 详情: 版权许可证的文本
|
||||
|
||||
### prevPageLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Previous Page'`
|
||||
- 详情: 上一页的文本
|
||||
|
||||
### nextPageLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Next Page'`
|
||||
- 详情: 下一页的文本
|
||||
|
||||
### notFound
|
||||
|
||||
- 类型: `NotFound | undefined`
|
||||
- 默认值: `undefined`
|
||||
- 详情: 404 页面配置
|
||||
|
||||
```ts
|
||||
interface NotFound {
|
||||
code?: string
|
||||
title?: string
|
||||
quote?: string
|
||||
linkLabel?: string
|
||||
linkText?: string
|
||||
}
|
||||
```
|
||||
|
||||
@ -20,10 +20,10 @@ tags:
|
||||
::: file-tree
|
||||
|
||||
- docs
|
||||
- en
|
||||
- **en** \# 英文目录
|
||||
- foo.md
|
||||
- README.md \# 英文首页
|
||||
- fr
|
||||
- **fr** \# 法文目录
|
||||
- foo.md
|
||||
- README.md \# 法文首页
|
||||
- foo.md
|
||||
@ -32,19 +32,49 @@ tags:
|
||||
|
||||
其中,`docs/en/` 用于保存 **英文** 文档,`docs/fr/` 保存 **法文** 文档,而 **中文** 则直接保存在 `docs/` 下。
|
||||
|
||||
::: important
|
||||
::: important 不同语言下的目录结构与文件名保持一致
|
||||
在不同的语言目录下,请尽量保持文件名和目录名的一致。这有助于在 切换语言时,主题能够正确的导航到 文章
|
||||
的不同的语言版本。
|
||||
:::
|
||||
|
||||
## vuepress 配置
|
||||
|
||||
接下来,在 `.vuepress/config.ts` 中配置:
|
||||
### 默认语言
|
||||
|
||||
在 `.vuepress/config.ts` 中,声明默认的语言:
|
||||
|
||||
::: code-tabs
|
||||
@tab .vuepress/config.ts
|
||||
|
||||
```js
|
||||
```ts
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
|
||||
export default defineUserConfig({
|
||||
// 声明默认的语言
|
||||
lang: 'zh-CN', // [!code ++]
|
||||
// 多语言下支持的各种语言 locales
|
||||
locales: {
|
||||
'/': { lang: 'zh-CN', title: '博客' }, // 默认语言 为 简体中文
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
### 添加其他语言
|
||||
|
||||
你需要为每个语言设置 `lang` 选项。即使你只在使用单个语言,你也必须在 `.vuepress/config.{js,ts}` 中设置 `lang`。
|
||||
|
||||
::: tip 为什么要这样做?
|
||||
要提供正确的语言环境文本,主题需要知道根文件夹以及每个多语言文件夹正在使用哪种语言。
|
||||
:::
|
||||
|
||||
在 `.vuepress/config.ts` 中配置:
|
||||
|
||||
::: code-tabs
|
||||
@tab .vuepress/config.ts
|
||||
|
||||
```ts
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
|
||||
export default defineUserConfig({
|
||||
@ -54,15 +84,24 @@ export default defineUserConfig({
|
||||
locales: {
|
||||
// 配置 不同 path 下的语言
|
||||
'/': { lang: 'zh-CN', title: '博客' }, // 默认语言 为 简体中文
|
||||
'/en/': { lang: 'en-US', title: 'Blog' }, // 英文
|
||||
'/fr/': { lang: 'fr-FR', title: 'Le blog' }, // 法语
|
||||
'/en/': { lang: 'en-US', title: 'Blog' }, // 英文 // [!code ++]
|
||||
'/fr/': { lang: 'fr-FR', title: 'Le blog' }, // 法语 // [!code ++]
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
`locales` 中的 `key` 对应着 `docs` 目录下的语言路径,同时,`key` 也将作为 不同语言的页面访问链接的前缀。
|
||||
**`locales` 配置中的 `key` 作为 `localPath`, 对应着 `docs` 目录下的语言路径,应该保证它们具有相同的命名。**
|
||||
|
||||
**同时,`key` (`localPath`) 也将作为 不同语言的页面访问链接的前缀。**
|
||||
|
||||
::: important 语言代码
|
||||
`locales` 配置中的 `key` 即 `localePath` 需要符合 [ISO 639](https://zh.wikipedia.org/wiki/ISO_639-1) 规范,
|
||||
对于非默认语言的,如 `英语` 应该为 `/en/`。
|
||||
|
||||
在 `locales[localePath]` 中, `lang` 为当前语言的 **语言代码**,请使用标准的 [BCP47](https://www.ietf.org/rfc/bcp/bcp47.txt) 语言代码。如, `英语` 应该为 `en-US`,(表示英语(美国))。
|
||||
:::
|
||||
|
||||
## 主题配置
|
||||
|
||||
@ -87,7 +126,7 @@ export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
// 主题内的多语言配置
|
||||
locales: {
|
||||
'/': {
|
||||
'/': { // [!code hl]
|
||||
// 当前语言显示在导航栏多语言下拉菜单的文本
|
||||
selectLanguageName: '简体中文',
|
||||
navbar: [
|
||||
@ -95,14 +134,14 @@ export default defineUserConfig({
|
||||
{ text: '博客', link: '/blog/' },
|
||||
]
|
||||
},
|
||||
'/en/': {
|
||||
'/en/': { // [!code hl]
|
||||
selectLanguageName: 'English',
|
||||
navbar: [
|
||||
{ text: 'Home', link: '/en/' },
|
||||
{ text: 'Blog', link: '/en/blog/' },
|
||||
]
|
||||
},
|
||||
'/fr/': {
|
||||
'/fr/': { // [!code hl]
|
||||
selectLanguageName: 'Français',
|
||||
navbar: [
|
||||
{ text: 'Accueil', link: '/fr/' },
|
||||
@ -116,4 +155,11 @@ export default defineUserConfig({
|
||||
|
||||
:::
|
||||
|
||||
更多 `locales` 配置请查看 [主题配置 > Locales 配置](../config/主题配置.md#locale-配置)
|
||||
主题 `theme.locales` 配置中的 `key` 应与 `vuepress` 配置中的 `locales` 配置中的 `key` 一致。
|
||||
|
||||
您应该为 `theme.locales[localePath]` 配置 `selectLanguageName` 用于在导航栏多语言下拉菜单中显示当前语言的名称。
|
||||
|
||||
更多 `locales` 配置请查看
|
||||
|
||||
- [主题配置 > Locales 配置](../config/主题配置.md#locale-配置) - 配置主题在不同语言下的行为。
|
||||
- [主题配置 > 多语言配置](../config/多语言配置.md) - 配置与语言相关的文本。
|
||||
|
||||
@ -15,9 +15,9 @@ interface Breadcrumb {
|
||||
current?: boolean
|
||||
}
|
||||
|
||||
const { page, theme } = useData<'post'>()
|
||||
const { page, blog } = useData<'post'>()
|
||||
const { isBlogPost } = useBlogPageData()
|
||||
const { home, blog, categories } = useInternalLink()
|
||||
const { home, blog: blogLink, categories } = useInternalLink()
|
||||
const sidebar = useSidebarData()
|
||||
|
||||
const hasBreadcrumb = computed(() => {
|
||||
@ -32,9 +32,8 @@ const breadcrumbList = computed<Breadcrumb[]>(() => {
|
||||
const list: Breadcrumb[] = [{ text: home.value.text, link: home.value.link }]
|
||||
|
||||
if (isBlogPost.value) {
|
||||
const blogConf = theme.value.blog || {}
|
||||
if (blogConf.postList ?? true)
|
||||
list.push({ text: blog.value.text, link: blog.value.link })
|
||||
if (blog.value.postList ?? true)
|
||||
list.push({ text: blogLink.value.text, link: blogLink.value.link })
|
||||
|
||||
const categoryList = page.value.categoryList ?? []
|
||||
for (const category of categoryList) {
|
||||
|
||||
@ -5,7 +5,7 @@ import { useReadingTimeLocale } from '@vuepress/plugin-reading-time/client'
|
||||
import { computed } from 'vue'
|
||||
import { useBlogPageData, useData, useInternalLink, useTagColors } from '../composables/index.js'
|
||||
|
||||
const { page, frontmatter: matter, theme } = useData<'post'>()
|
||||
const { page, frontmatter: matter, theme, blog } = useData<'post'>()
|
||||
const colors = useTagColors()
|
||||
const readingTime = useReadingTimeLocale()
|
||||
const { tags: tagsLink } = useInternalLink()
|
||||
@ -22,8 +22,7 @@ const createTime = computed(() => {
|
||||
})
|
||||
|
||||
const tags = computed(() => {
|
||||
const blog = theme.value.blog || {}
|
||||
const tagTheme = blog.tagsTheme ?? 'colored'
|
||||
const tagTheme = blog.value.tagsTheme ?? 'colored'
|
||||
if (matter.value.tags) {
|
||||
return matter.value.tags.slice(0, 4).map(tag => ({
|
||||
name: tag,
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
import type { PlumeThemeBlogPostItem } from '../../shared/index.js'
|
||||
import { computed } from 'vue'
|
||||
import { useRouteLocale } from 'vuepress/client'
|
||||
import { useLocalePostList } from './blog-data.js'
|
||||
import { getPresetLocaleData } from './preset-locales.js'
|
||||
import { useData } from './data.js'
|
||||
import { useThemeData } from './theme-data.js'
|
||||
|
||||
export type ShortPostItem = Pick<PlumeThemeBlogPostItem, 'title' | 'path' | 'createTime'>
|
||||
|
||||
export function useArchives() {
|
||||
const locale = useRouteLocale()
|
||||
const themeData = useThemeData()
|
||||
const list = useLocalePostList()
|
||||
const { theme } = useData()
|
||||
|
||||
const archives = computed(() => {
|
||||
const archives: { title: string, label: string, list: ShortPostItem[] }[] = []
|
||||
const countLocale = getPresetLocaleData(locale.value, 'archiveTotal')
|
||||
const countLocale = theme.value.archiveTotalText || themeData.value.archiveTotalText
|
||||
|
||||
list.value.forEach((item) => {
|
||||
const createTime = item.createTime?.split(/\s|T/)[0] || ''
|
||||
@ -30,7 +31,7 @@ export function useArchives() {
|
||||
})
|
||||
|
||||
archives.forEach((item) => {
|
||||
item.label = countLocale.replace('{count}', item.list.length.toString())
|
||||
item.label = countLocale?.replace('{count}', item.list.length.toString()) || ''
|
||||
})
|
||||
|
||||
return archives
|
||||
|
||||
@ -2,7 +2,7 @@ import type { PresetLocale } from '../../shared/index.js'
|
||||
import { computed } from 'vue'
|
||||
import { useRouteLocale } from 'vuepress/client'
|
||||
import { useData } from './data.js'
|
||||
import { getPresetLocaleData } from './preset-locales.js'
|
||||
import { useThemeData } from './theme-data.js'
|
||||
|
||||
export interface InternalLink {
|
||||
text: string
|
||||
@ -10,13 +10,14 @@ export interface InternalLink {
|
||||
}
|
||||
|
||||
export function useInternalLink() {
|
||||
const { blog } = useData()
|
||||
const { blog, theme } = useData()
|
||||
const themeData = useThemeData()
|
||||
const routeLocale = useRouteLocale()
|
||||
|
||||
function resolveLink(name: keyof PresetLocale, link: string): InternalLink {
|
||||
return {
|
||||
link: (routeLocale.value + link).replace(/\/+/g, '/'),
|
||||
text: getPresetLocaleData(routeLocale.value, name),
|
||||
text: theme.value[`${name}Text`] || themeData.value[`${name}Text`],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import type { App } from 'vuepress'
|
||||
import type { PlumeThemeData, PlumeThemeLocaleOptions } from '../../shared/index.js'
|
||||
import { entries, fromEntries, getLocaleConfig } from '@vuepress/helper'
|
||||
import { hasOwn, uniq } from '@pengzhanbo/utils'
|
||||
import { entries, fromEntries, getLocaleConfig, isPlainObject } from '@vuepress/helper'
|
||||
import { LOCALE_OPTIONS } from '../locales/index.js'
|
||||
import { THEME_NAME } from '../utils/index.js'
|
||||
|
||||
@ -41,8 +42,7 @@ const FALLBACK_OPTIONS: PlumeThemeData = {
|
||||
|
||||
export function resolveLocaleOptions(app: App, { locales, ...options }: PlumeThemeLocaleOptions): PlumeThemeLocaleOptions {
|
||||
const resolvedOptions: PlumeThemeLocaleOptions = {
|
||||
...FALLBACK_OPTIONS,
|
||||
...options,
|
||||
...mergeLocaleOptions(FALLBACK_OPTIONS, options),
|
||||
locales: getLocaleConfig({
|
||||
app,
|
||||
name: THEME_NAME,
|
||||
@ -53,10 +53,31 @@ export function resolveLocaleOptions(app: App, { locales, ...options }: PlumeThe
|
||||
...locales,
|
||||
}).map(([locale, opt]) => [
|
||||
locale,
|
||||
{ ...options, ...opt },
|
||||
mergeLocaleOptions(options, opt),
|
||||
]),
|
||||
),
|
||||
}),
|
||||
}
|
||||
return resolvedOptions
|
||||
}
|
||||
|
||||
function mergeLocaleOptions(target: PlumeThemeData, source: PlumeThemeData): PlumeThemeData {
|
||||
const res: PlumeThemeData = {}
|
||||
const keys = uniq([...Object.keys(target), ...Object.keys(source)]) as (keyof PlumeThemeData)[]
|
||||
for (const key of keys) {
|
||||
if (hasOwn(source, key)) {
|
||||
const value = source[key]
|
||||
const targetValue = target[key]
|
||||
if (isPlainObject(targetValue) && isPlainObject(value)) {
|
||||
res[key] = Object.assign({}, targetValue, value) as any
|
||||
}
|
||||
else {
|
||||
res[key] = value as any
|
||||
}
|
||||
}
|
||||
else {
|
||||
res[key] = target[key]
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import type { App } from 'vuepress'
|
||||
import type { NavItem, PlumeThemeLocaleOptions } from '../../shared/index.js'
|
||||
import { entries, getRootLangPath, isBoolean, isPlainObject } from '@vuepress/helper'
|
||||
import { PRESET_LOCALES } from '../locales/index.js'
|
||||
import { entries, isBoolean, isPlainObject } from '@vuepress/helper'
|
||||
import { withBase } from '../utils/index.js'
|
||||
|
||||
const EXCLUDE_LIST = ['locales', 'sidebar', 'navbar', 'notes', 'sidebar', 'article', 'avatar']
|
||||
@ -10,7 +9,6 @@ const EXCLUDE_LOCALE_LIST = [...EXCLUDE_LIST, 'blog', 'appearance']
|
||||
|
||||
export function resolveThemeData(app: App, options: PlumeThemeLocaleOptions): PlumeThemeLocaleOptions {
|
||||
const themeData: PlumeThemeLocaleOptions = { locales: {} }
|
||||
const root = getRootLangPath(app)
|
||||
|
||||
entries(options).forEach(([key, value]) => {
|
||||
if (!EXCLUDE_LIST.includes(key))
|
||||
@ -61,27 +59,26 @@ export function resolveThemeData(app: App, options: PlumeThemeLocaleOptions): Pl
|
||||
// home | blog | tags | archives
|
||||
if (opt.navbar !== false && (!opt.navbar || opt.navbar.length === 0)) {
|
||||
// fallback navbar option
|
||||
const localePath = locale === '/' ? root : locale
|
||||
const navbar: NavItem[] = [{
|
||||
text: PRESET_LOCALES[localePath].home,
|
||||
text: opt.homeText || options.homeText || 'Home',
|
||||
link: locale,
|
||||
}]
|
||||
if (options.blog !== false) {
|
||||
const blog = options.blog || {}
|
||||
const blogLink = blog.link || '/blog/'
|
||||
navbar.push({
|
||||
text: PRESET_LOCALES[localePath].blog,
|
||||
text: opt.blogText || options.blogText || 'Blog',
|
||||
link: withBase(blogLink, locale),
|
||||
})
|
||||
if (blog.tags !== false) {
|
||||
navbar.push({
|
||||
text: PRESET_LOCALES[localePath].tag,
|
||||
text: opt.tagText || options.tagText || 'Tags',
|
||||
link: withBase(blog.tagsLink || `${blogLink}/tags/`, locale),
|
||||
})
|
||||
}
|
||||
if (blog.archives !== false) {
|
||||
navbar.push({
|
||||
text: PRESET_LOCALES[localePath].archive,
|
||||
text: opt.archiveText || options.archiveText || 'Archives',
|
||||
link: withBase(blog.archivesLink || `${blogLink}/archives/`, locale),
|
||||
})
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import { plumeTheme } from './theme.js'
|
||||
|
||||
export * from '../shared/index.js'
|
||||
export * from './defineConfig.js'
|
||||
export * from './types.js'
|
||||
|
||||
export { plumeTheme }
|
||||
|
||||
|
||||
@ -37,6 +37,13 @@ export const deLocale: PlumeThemeLocaleData = {
|
||||
linkText: 'Zur Startseite',
|
||||
},
|
||||
|
||||
homeText: 'Startseite',
|
||||
blogText: 'Blog',
|
||||
tagText: 'Tag',
|
||||
archiveText: 'Archiv',
|
||||
categoryText: 'Kategorie',
|
||||
archiveTotalText: '{count} Beiträge',
|
||||
|
||||
encryptButtonText: 'Bestätigen',
|
||||
encryptPlaceholder: 'Bitte Passwort eingeben',
|
||||
encryptGlobalText: 'Diese Website ist nur mit Passwort zugänglich',
|
||||
@ -49,12 +56,6 @@ export const deLocale: PlumeThemeLocaleData = {
|
||||
}
|
||||
|
||||
export const dePresetLocale: PresetLocale = {
|
||||
'home': 'Startseite',
|
||||
'blog': 'Blog',
|
||||
'tag': 'Tag',
|
||||
'archive': 'Archiv',
|
||||
'category': 'Kategorie',
|
||||
'archiveTotal': '{count} Beiträge',
|
||||
|
||||
// ------ copyright license ------
|
||||
'CC0': 'CC0 1.0 Universell',
|
||||
|
||||
@ -28,6 +28,13 @@ export const enLocale: PlumeThemeLocaleData = {
|
||||
encryptGlobalText: 'Only password can access this site',
|
||||
encryptPageText: 'Only password can access this page',
|
||||
|
||||
homeText: 'Home',
|
||||
blogText: 'Blog',
|
||||
tagText: 'Tags',
|
||||
archiveText: 'Archives',
|
||||
categoryText: 'Categories',
|
||||
archiveTotalText: '{count} articles',
|
||||
|
||||
footer: {
|
||||
message:
|
||||
'Powered by <a target="_blank" href="https://v2.vuepress.vuejs.org/">VuePress</a> & <a target="_blank" href="https://theme-plume.vuejs.press">vuepress-theme-plume</a>',
|
||||
@ -35,13 +42,6 @@ export const enLocale: PlumeThemeLocaleData = {
|
||||
}
|
||||
|
||||
export const enPresetLocale: PresetLocale = {
|
||||
'home': 'Home',
|
||||
'blog': 'Blog',
|
||||
'tag': 'Tags',
|
||||
'archive': 'Archives',
|
||||
'category': 'Categories',
|
||||
'archiveTotal': '{count} articles',
|
||||
|
||||
// ------ copyright license ------
|
||||
'CC0': 'CC0 1.0 Universal',
|
||||
'CC-BY-4.0': 'Attribution 4.0 International',
|
||||
|
||||
@ -37,6 +37,13 @@ export const frLocale: PlumeThemeLocaleData = {
|
||||
linkText: 'Retour à l\'accueil',
|
||||
},
|
||||
|
||||
homeText: 'Accueil',
|
||||
blogText: 'Blog',
|
||||
tagText: 'Étiquette',
|
||||
archiveText: 'Archives',
|
||||
categoryText: 'Catégorie',
|
||||
archiveTotalText: '{count} articles',
|
||||
|
||||
encryptButtonText: 'Confirmer',
|
||||
encryptPlaceholder: 'Veuillez entrer le mot de passe',
|
||||
encryptGlobalText: 'Ce site n\'est accessible qu\'avec un mot de passe',
|
||||
@ -49,13 +56,6 @@ export const frLocale: PlumeThemeLocaleData = {
|
||||
}
|
||||
|
||||
export const frPresetLocale: PresetLocale = {
|
||||
'home': 'Accueil',
|
||||
'blog': 'Blog',
|
||||
'tag': 'Étiquette',
|
||||
'archive': 'Archives',
|
||||
'category': 'Catégorie',
|
||||
'archiveTotal': '{count} articles',
|
||||
|
||||
// ------ copyright license ------
|
||||
'CC0': 'CC0 1.0 Universel',
|
||||
'CC-BY-4.0': 'Attribution 4.0 International',
|
||||
|
||||
@ -37,6 +37,13 @@ export const jaLocale: PlumeThemeLocaleData = {
|
||||
linkText: 'ホームに戻る',
|
||||
},
|
||||
|
||||
homeText: 'ホーム',
|
||||
blogText: 'ブログ',
|
||||
tagText: 'タグ',
|
||||
archiveText: 'アーカイブ',
|
||||
categoryText: 'カテゴリー',
|
||||
archiveTotalText: '{count} 件',
|
||||
|
||||
encryptButtonText: '確認',
|
||||
encryptPlaceholder: 'パスワードを入力してください',
|
||||
encryptGlobalText: 'このサイトはパスワードでのみアクセス可能です',
|
||||
@ -49,13 +56,6 @@ export const jaLocale: PlumeThemeLocaleData = {
|
||||
}
|
||||
|
||||
export const jaPresetLocale: PresetLocale = {
|
||||
'home': 'ホーム',
|
||||
'blog': 'ブログ',
|
||||
'tag': 'タグ',
|
||||
'archive': 'アーカイブ',
|
||||
'category': 'カテゴリー',
|
||||
'archiveTotal': '{count} 件',
|
||||
|
||||
// ------ copyright license ------
|
||||
'CC0': 'CC0 1.0 パブリックドメイン',
|
||||
'CC-BY-4.0': '表示 4.0 国際',
|
||||
|
||||
@ -37,6 +37,13 @@ export const ruLocale: PlumeThemeLocaleData = {
|
||||
linkText: 'Вернуться на главную',
|
||||
},
|
||||
|
||||
homeText: 'Главная',
|
||||
blogText: 'Блог',
|
||||
tagText: 'Теги',
|
||||
archiveText: 'Архив',
|
||||
categoryText: 'Категории',
|
||||
archiveTotalText: '{count} статей',
|
||||
|
||||
encryptButtonText: 'Подтвердить',
|
||||
encryptPlaceholder: 'Введите пароль',
|
||||
encryptGlobalText: 'Доступ к сайту только по паролю',
|
||||
@ -49,13 +56,6 @@ export const ruLocale: PlumeThemeLocaleData = {
|
||||
}
|
||||
|
||||
export const ruPresetLocale: PresetLocale = {
|
||||
'home': 'Главная',
|
||||
'blog': 'Блог',
|
||||
'tag': 'Теги',
|
||||
'archive': 'Архив',
|
||||
'category': 'Категории',
|
||||
'archiveTotal': '{count} статей',
|
||||
|
||||
// ------ copyright license ------
|
||||
'CC0': 'CC0 1.0 Универсальная',
|
||||
'CC-BY-4.0': 'Атрибуция 4.0 Международный',
|
||||
|
||||
@ -37,6 +37,13 @@ export const zhTwLocale: PlumeThemeLocaleData = {
|
||||
linkText: '返回首頁',
|
||||
},
|
||||
|
||||
homeText: '首頁',
|
||||
blogText: '博客',
|
||||
tagText: '標籤',
|
||||
archiveText: '歸檔',
|
||||
categoryText: '分類',
|
||||
archiveTotalText: '{count} 篇',
|
||||
|
||||
encryptButtonText: '確認',
|
||||
encryptPlaceholder: '請輸入密碼',
|
||||
encryptGlobalText: '本站只允許密碼訪問',
|
||||
@ -49,13 +56,6 @@ export const zhTwLocale: PlumeThemeLocaleData = {
|
||||
}
|
||||
|
||||
export const zhTwPresetLocale: PresetLocale = {
|
||||
'home': '首頁',
|
||||
'blog': '博客',
|
||||
'tag': '標籤',
|
||||
'archive': '歸檔',
|
||||
'category': '分類',
|
||||
'archiveTotal': '{count} 篇',
|
||||
|
||||
// ------ copyright license ------
|
||||
'CC0': 'CC0 1.0 通用',
|
||||
'CC-BY-4.0': '署名 4.0 國際',
|
||||
|
||||
@ -36,6 +36,13 @@ export const zhLocale: PlumeThemeLocaleData = {
|
||||
linkText: '返回首页',
|
||||
},
|
||||
|
||||
homeText: '首页',
|
||||
blogText: '博客',
|
||||
tagText: '标签',
|
||||
archiveText: '归档',
|
||||
categoryText: '分类',
|
||||
archiveTotalText: '{count} 篇',
|
||||
|
||||
encryptButtonText: '确认',
|
||||
encryptPlaceholder: '请输入密码',
|
||||
encryptGlobalText: '本站只允许密码访问',
|
||||
@ -48,13 +55,6 @@ export const zhLocale: PlumeThemeLocaleData = {
|
||||
}
|
||||
|
||||
export const zhPresetLocale: PresetLocale = {
|
||||
'home': '首页',
|
||||
'blog': '博客',
|
||||
'tag': '标签',
|
||||
'archive': '归档',
|
||||
'category': '分类',
|
||||
'archiveTotal': '{count} 篇',
|
||||
|
||||
// ------ copyright license ------
|
||||
'CC0': 'CC0 1.0 通用',
|
||||
'CC-BY-4.0': '署名 4.0 国际',
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import type { App, Page } from 'vuepress/core'
|
||||
import type { PlumeThemeLocaleOptions } from '../../shared/index.js'
|
||||
import { getRootLang, getRootLangPath } from '@vuepress/helper'
|
||||
import { getRootLang } from '@vuepress/helper'
|
||||
import { createPage } from 'vuepress/core'
|
||||
import { PRESET_LOCALES } from '../locales/index.js'
|
||||
import { withBase } from '../utils/index.js'
|
||||
|
||||
export async function createPages(app: App, localeOption: PlumeThemeLocaleOptions) {
|
||||
@ -11,26 +10,20 @@ export async function createPages(app: App, localeOption: PlumeThemeLocaleOption
|
||||
|
||||
const pageList: Promise<Page>[] = []
|
||||
const locales = localeOption.locales || {}
|
||||
const rootPath = getRootLangPath(app)
|
||||
const rootLang = getRootLang(app)
|
||||
|
||||
const blog = localeOption.blog || {}
|
||||
const link = blog.link || '/blog/'
|
||||
|
||||
const getTitle = (locale: string, key: string) => {
|
||||
const opt = PRESET_LOCALES[locale] || PRESET_LOCALES[rootPath] || {}
|
||||
return opt[key] || ''
|
||||
}
|
||||
|
||||
for (const localePath of Object.keys(locales)) {
|
||||
const lang = app.siteData.locales?.[localePath]?.lang || rootLang
|
||||
const locale = localePath === '/' ? rootPath : localePath
|
||||
const opt = locales[localePath]
|
||||
|
||||
// 添加 博客页面
|
||||
if (blog.postList !== false) {
|
||||
pageList.push(createPage(app, {
|
||||
path: withBase(link, localePath),
|
||||
frontmatter: { lang, _pageLayout: 'blog', title: getTitle(locale, 'blog') },
|
||||
frontmatter: { lang, _pageLayout: 'blog', title: opt.blogText || localeOption.blogText || 'Blog' },
|
||||
}))
|
||||
}
|
||||
|
||||
@ -38,7 +31,7 @@ export async function createPages(app: App, localeOption: PlumeThemeLocaleOption
|
||||
if (blog.tags !== false) {
|
||||
pageList.push(createPage(app, {
|
||||
path: withBase(blog.tagsLink || `${link}/tags/`, localePath),
|
||||
frontmatter: { lang, _pageLayout: 'blog-tags', title: getTitle(locale, 'tag') },
|
||||
frontmatter: { lang, _pageLayout: 'blog-tags', title: opt.tagText || localeOption.tagText || 'Tags' },
|
||||
}))
|
||||
}
|
||||
|
||||
@ -46,7 +39,7 @@ export async function createPages(app: App, localeOption: PlumeThemeLocaleOption
|
||||
if (blog.archives !== false) {
|
||||
pageList.push(createPage(app, {
|
||||
path: withBase(blog.archivesLink || `${link}/archives/`, localePath),
|
||||
frontmatter: { lang, _pageLayout: 'blog-archives', title: getTitle(locale, 'archive') },
|
||||
frontmatter: { lang, _pageLayout: 'blog-archives', title: opt.archiveText || localeOption.archiveText || 'Archives' },
|
||||
}))
|
||||
}
|
||||
|
||||
@ -54,7 +47,7 @@ export async function createPages(app: App, localeOption: PlumeThemeLocaleOption
|
||||
if (blog.categories !== false) {
|
||||
pageList.push(createPage(app, {
|
||||
path: withBase(blog.categoriesLink || `${link}/categories/`, localePath),
|
||||
frontmatter: { lang, _pageLayout: 'blog-categories', title: getTitle(locale, 'category') },
|
||||
frontmatter: { lang, _pageLayout: 'blog-categories', title: opt.categoryText || localeOption.categoryText || 'Categories' },
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,14 +50,7 @@ export type SocialLinkIconUnion =
|
||||
|
||||
export type SocialLinkIcon = SocialLinkIconUnion | { svg: string, name?: string }
|
||||
|
||||
export interface PresetLocale extends Record<CopyrightLicense, string> {
|
||||
home: string
|
||||
blog: string
|
||||
tag: string
|
||||
archive: string
|
||||
category: string
|
||||
archiveTotal: string
|
||||
}
|
||||
export interface PresetLocale extends Record<CopyrightLicense, string> {}
|
||||
|
||||
export type KnownCopyrightLicense =
|
||||
| 'CC-BY-4.0'
|
||||
|
||||
@ -299,6 +299,32 @@ export interface PlumeThemeLocaleData extends LocaleData {
|
||||
linkText?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页文本,用于默认生成的导航栏、面包屑导航中
|
||||
*/
|
||||
homeText?: string
|
||||
/**
|
||||
* 博客文本,用于默认生成的导航栏、面包屑导航中
|
||||
*/
|
||||
blogText?: string
|
||||
/**
|
||||
* 标签文本,用于默认生成的导航栏、博客标签页中
|
||||
*/
|
||||
tagText?: string
|
||||
/**
|
||||
* 归档文本,用于默认生成的导航栏、博客归档页中
|
||||
*/
|
||||
archiveText?: string
|
||||
/**
|
||||
* 分类文本,用于默认生成的导航栏、博客分类页中
|
||||
*/
|
||||
categoryText?: string
|
||||
/**
|
||||
* 博客总数文本,用于默认生成的导航栏、博客归档页中
|
||||
* @default '{count} articles''
|
||||
*/
|
||||
archiveTotalText?: string
|
||||
|
||||
/**
|
||||
* 全站加密时的提示
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user