feat: make blog config options and navbar versions dropdown label translatable (#5371)

* Translate versions dropdown label

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Make blog options tranlatable

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Fix names

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Rename functions

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Rename translations path

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Update docs

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Update Chinese translations

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Remove space

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Update docs

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Add jest test

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Fix copyright typing

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Update test

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Update options

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>

* Fix test

Signed-off-by: Josh-Cena <sidachen2003@gmail.com>
This commit is contained in:
Joshua Chen 2021-08-20 23:11:59 +08:00 committed by GitHub
parent 08597045ed
commit 8e1cde135c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 293 additions and 17 deletions

View file

@ -0,0 +1,64 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`getContentTranslationFiles should return translation files matching snapshot 1`] = `
Array [
Object {
"content": Object {
"description": Object {
"description": "The description for the blog used in SEO",
"message": "Someone's random blog",
},
"sidebar.title": Object {
"description": "The label for the left sidebar",
"message": "All my posts",
},
"title": Object {
"description": "The title for the blog used in SEO",
"message": "My blog",
},
},
"path": "options",
},
]
`;
exports[`translateContent should return translated loaded content matching snapshot 1`] = `
Object {
"blogListPaginated": Array [
Object {
"items": Array [
"hello",
],
"metadata": Object {
"blogDescription": "Someone's random blog (translated)",
"blogTitle": "My blog (translated)",
"nextPage": null,
"page": 1,
"permalink": "/",
"postsPerPage": 10,
"previousPage": null,
"totalCount": 1,
"totalPages": 1,
},
},
],
"blogPosts": Array [
Object {
"id": "hello",
"metadata": Object {
"date": 2021-07-19T00:00:00.000Z,
"description": "/blog/2021/06/19/hello",
"formattedDate": "June 19, 2021",
"permalink": "/blog/2021/06/19/hello",
"source": "/blog/2021/06/19/hello",
"tags": Array [],
"title": "Hello",
"truncated": true,
},
},
],
"blogSidebarTitle": "All my posts (translated)",
"blogTags": Object {},
"blogTagsListPath": "/tags",
}
`;

View file

@ -29,7 +29,7 @@ test('should accept correctly defined user options', () => {
const {value, error} = PluginOptionSchema.validate(userOptions);
expect(value).toEqual({
...userOptions,
feedOptions: {type: ['rss'], title: 'myTitle'},
feedOptions: {type: ['rss'], title: 'myTitle', copyright: ''},
});
expect(error).toBe(undefined);
});
@ -78,7 +78,7 @@ test('should convert all feed type to array with other feed type', () => {
});
expect(value).toEqual({
...DEFAULT_OPTIONS,
feedOptions: {type: ['rss', 'atom']},
feedOptions: {type: ['rss', 'atom'], copyright: ''},
});
});
@ -106,7 +106,7 @@ test('should have array with rss + atom, title for missing feed type', () => {
});
expect(value).toEqual({
...DEFAULT_OPTIONS,
feedOptions: {type: ['rss', 'atom'], title: 'title'},
feedOptions: {type: ['rss', 'atom'], title: 'title', copyright: ''},
});
});

View file

@ -0,0 +1,92 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {BlogPost, BlogContent, PluginOptions} from '../types';
import {getTranslationFiles, translateContent} from '../translations';
import {DEFAULT_OPTIONS} from '../pluginOptionSchema';
import {updateTranslationFileMessages} from '@docusaurus/utils';
const sampleBlogOptions: PluginOptions = {
...DEFAULT_OPTIONS,
blogSidebarTitle: 'All my posts',
blogTitle: 'My blog',
blogDescription: "Someone's random blog",
};
const sampleBlogPosts: BlogPost[] = [
{
id: 'hello',
metadata: {
permalink: '/blog/2021/06/19/hello',
source: '/blog/2021/06/19/hello',
description: '/blog/2021/06/19/hello',
date: new Date(2021, 6, 19),
formattedDate: 'June 19, 2021',
tags: [],
title: 'Hello',
truncated: true,
},
},
];
const sampleBlogContent: BlogContent = {
blogSidebarTitle: sampleBlogOptions.blogSidebarTitle,
blogListPaginated: [
{
items: ['hello'],
metadata: {
permalink: '/',
page: 1,
postsPerPage: 10,
totalPages: 1,
totalCount: 1,
previousPage: null,
nextPage: null,
blogTitle: sampleBlogOptions.blogTitle,
blogDescription: sampleBlogOptions.blogDescription,
},
},
],
blogPosts: sampleBlogPosts,
blogTags: {},
blogTagsListPath: '/tags',
};
function getSampleTranslationFiles() {
return getTranslationFiles(sampleBlogOptions);
}
function getSampleTranslationFilesTranslated() {
const translationFiles = getSampleTranslationFiles();
return translationFiles.map((translationFile) =>
updateTranslationFileMessages(
translationFile,
(message) => `${message} (translated)`,
),
);
}
describe('getContentTranslationFiles', () => {
test('should return translation files matching snapshot', async () => {
expect(getSampleTranslationFiles()).toMatchSnapshot();
});
});
describe('translateContent', () => {
test('should not translate anything if translation files are untranslated', () => {
const translationFiles = getSampleTranslationFiles();
expect(translateContent(sampleBlogContent, translationFiles)).toEqual(
sampleBlogContent,
);
});
test('should return translated loaded content matching snapshot', () => {
const translationFiles = getSampleTranslationFilesTranslated();
expect(
translateContent(sampleBlogContent, translationFiles),
).toMatchSnapshot();
});
});

View file

@ -22,6 +22,7 @@ import {
STATIC_DIR_NAME,
DEFAULT_PLUGIN_ID,
} from '@docusaurus/core/lib/constants';
import {translateContent, getTranslationFiles} from './translations';
import {flatten, take} from 'lodash';
import {
@ -102,6 +103,10 @@ export default function pluginContentBlog(
);
},
async getTranslationFiles() {
return getTranslationFiles(options);
},
// Fetches blog contents and returns metadata for the necessary routes.
async loadContent() {
const {
@ -109,6 +114,7 @@ export default function pluginContentBlog(
routeBasePath,
blogDescription,
blogTitle,
blogSidebarTitle,
} = options;
const blogPosts: BlogPost[] = await generateBlogPosts(
@ -119,6 +125,7 @@ export default function pluginContentBlog(
if (!blogPosts.length) {
return {
blogSidebarTitle,
blogPosts: [],
blogListPaginated: [],
blogTags: {},
@ -192,6 +199,7 @@ export default function pluginContentBlog(
Object.keys(blogTags).length > 0 ? tagsPath : null;
return {
blogSidebarTitle,
blogPosts,
blogListPaginated,
blogTags,
@ -213,6 +221,7 @@ export default function pluginContentBlog(
const {addRoute, createData} = actions;
const {
blogSidebarTitle,
blogPosts,
blogListPaginated,
blogTags,
@ -233,7 +242,7 @@ export default function pluginContentBlog(
`blog-post-list-prop-${pluginId}.json`,
JSON.stringify(
{
title: options.blogSidebarTitle,
title: blogSidebarTitle,
items: sidebarBlogPosts.map((blogPost) => ({
title: blogPost.metadata.title,
permalink: blogPost.metadata.permalink,
@ -371,6 +380,10 @@ export default function pluginContentBlog(
}
},
translateContent({content, translationFiles}) {
return translateContent(content, translationFiles);
},
configureWebpack(
_config: Configuration,
isServer: boolean,
@ -461,7 +474,7 @@ export default function pluginContentBlog(
},
async postBuild({outDir}: Props) {
if (!options.feedOptions?.type) {
if (!options.feedOptions.type) {
return;
}

View file

@ -13,9 +13,10 @@ import {
URISchema,
} from '@docusaurus/utils-validation';
import {GlobExcludeDefault} from '@docusaurus/utils';
import {PluginOptions} from './types';
export const DEFAULT_OPTIONS = {
feedOptions: {type: ['rss', 'atom']},
export const DEFAULT_OPTIONS: PluginOptions = {
feedOptions: {type: ['rss', 'atom'], copyright: ''},
beforeDefaultRehypePlugins: [],
beforeDefaultRemarkPlugins: [],
admonitions: {},
@ -39,7 +40,7 @@ export const DEFAULT_OPTIONS = {
editLocalizedFiles: false,
};
export const PluginOptionSchema = Joi.object({
export const PluginOptionSchema = Joi.object<PluginOptions>({
path: Joi.string().default(DEFAULT_OPTIONS.path),
routeBasePath: Joi.string()
// '' not allowed, see https://github.com/facebook/docusaurus/issues/3374
@ -96,7 +97,14 @@ export const PluginOptionSchema = Joi.object({
.default(DEFAULT_OPTIONS.feedOptions.type),
title: Joi.string().allow(''),
description: Joi.string().allow(''),
copyright: Joi.string(),
// only add default value when user actually wants a feed (type is not null)
copyright: Joi.when('type', {
is: Joi.any().valid(null),
then: Joi.string().optional(),
otherwise: Joi.string()
.allow('')
.default(DEFAULT_OPTIONS.feedOptions.copyright),
}),
language: Joi.string(),
}).default(DEFAULT_OPTIONS.feedOptions),
});

View file

@ -0,0 +1,63 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import type {BlogContent, PluginOptions, BlogPaginated} from './types';
import type {TranslationFileContent, TranslationFiles} from '@docusaurus/types';
function translateListPage(
blogListPaginated: BlogPaginated[],
translations: TranslationFileContent,
) {
return blogListPaginated.map((page) => {
const {items, metadata} = page;
return {
items,
metadata: {
...metadata,
blogTitle: translations.title.message,
blogDescription: translations.description.message,
},
};
});
}
export function getTranslationFiles(options: PluginOptions): TranslationFiles {
return [
{
path: 'options',
content: {
title: {
message: options.blogTitle,
description: 'The title for the blog used in SEO',
},
description: {
message: options.blogDescription,
description: 'The description for the blog used in SEO',
},
'sidebar.title': {
message: options.blogSidebarTitle,
description: 'The label for the left sidebar',
},
},
},
];
}
export function translateContent(
content: BlogContent,
translationFiles: TranslationFiles,
): BlogContent {
const [{content: optonsTranslations}] = translationFiles;
return {
...content,
blogSidebarTitle: optonsTranslations['sidebar.title'].message,
blogListPaginated: translateListPage(
content.blogListPaginated,
optonsTranslations,
),
};
}

View file

@ -15,6 +15,7 @@ import type {
export type BlogContentPaths = ContentPaths;
export interface BlogContent {
blogSidebarTitle: string;
blogPosts: BlogPost[];
blogListPaginated: BlogPaginated[];
blogTags: BlogTags;
@ -48,7 +49,7 @@ export interface PluginOptions extends RemarkAndRehypePluginOptions {
truncateMarker: RegExp;
showReadingTime: boolean;
feedOptions: {
type?: [FeedType] | null;
type?: FeedType[] | null;
title?: string;
description?: string;
copyright: string;

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " بواسطة {user}",
"theme.lastUpdated.lastUpdatedAtBy": "آخر تحديث{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "الوسوم:",
"theme.tags.tagsPageLink": "عرض كل الوسوم",
"theme.tags.tagsPageTitle": "الوسوم"

View file

@ -105,6 +105,8 @@
"theme.lastUpdated.lastUpdatedAtBy___DESCRIPTION": "The sentence used to display when a page has been last updated, and by who",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel___DESCRIPTION": "The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.navbar.mobileVersionsDropdown.label___DESCRIPTION": "The label for the navbar versions dropdown on mobile view",
"theme.tags.tagsListLabel": "Tags:",
"theme.tags.tagsListLabel___DESCRIPTION": "The label alongside a tag list",
"theme.tags.tagsPageLink": "View All Tags",

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": "{user} দ্বারা",
"theme.lastUpdated.lastUpdatedAtBy": "সর্বশেষ সংষ্করণ{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← মেন মেনুতে যান",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "ট্যাগ্স:",
"theme.tags.tagsPageLink": "সমস্ত ট্যাগ্স দেখুন",
"theme.tags.tagsPageTitle": "ট্যাগ্স"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " od {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Naposledy aktualizováno{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Zpět na hlavní menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Tagy:",
"theme.tags.tagsPageLink": "Zobrazit všechny tagy",
"theme.tags.tagsPageTitle": "Tagy"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " af {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Senest opdateret{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Tags:",
"theme.tags.tagsPageLink": "Se alle Tags",
"theme.tags.tagsPageTitle": "Tags"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " von {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Letztes Update{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Tags:",
"theme.tags.tagsPageLink": "Alle Tags anzeigen",
"theme.tags.tagsPageTitle": "Tags"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " por {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Última actualización{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Etiquetas:",
"theme.tags.tagsPageLink": "Ver Todas las Etiquetas",
"theme.tags.tagsPageTitle": "Etiquetas"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " توسط {user}",
"theme.lastUpdated.lastUpdatedAtBy": "آخرین بروزرسانی در {atDate} توسط {byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "→ بازگشت به منو اصلی",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "برچسب ها:",
"theme.tags.tagsPageLink": "مشاهده تمام برچسب ها",
"theme.tags.tagsPageTitle": "برچسب ها"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " ni {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Huling inapdeyt{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Mga Tag:",
"theme.tags.tagsPageLink": "Tingnan Lahat ng mga Tag",
"theme.tags.tagsPageTitle": "Mga Tag"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " par {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Dernière mise à jour{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Retour au menu principal",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Tags :",
"theme.tags.tagsPageLink": "Voir tous les tags",
"theme.tags.tagsPageTitle": "Tags"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " על ידי {user}",
"theme.lastUpdated.lastUpdatedAtBy": "עודכן{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← חזרה לתפריט הראשי",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "תגיות:",
"theme.tags.tagsPageLink": "כל התגיות",
"theme.tags.tagsPageTitle": "תגיות"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " {user} द्वारा",
"theme.lastUpdated.lastUpdatedAtBy": "आखरी अपडेट{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← मुख्य मेनू में वापस जाएं",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "टैग:",
"theme.tags.tagsPageLink": "सारे टैग देखें",
"theme.tags.tagsPageTitle": "टैग"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": "{user}が",
"theme.lastUpdated.lastUpdatedAtBy": "{atDate}{byUser}最終更新",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "タグ:",
"theme.tags.tagsPageLink": "全てのタグを見る",
"theme.tags.tagsPageTitle": "タグ"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " {user}가",
"theme.lastUpdated.lastUpdatedAtBy": "{atDate}{byUser} 마지막으로 업데이트했습니다.",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "태그:",
"theme.tags.tagsPageLink": "모든 태그 보기",
"theme.tags.tagsPageTitle": "태그"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " przez {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Ostatnia aktualizacja{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Tagi:",
"theme.tags.tagsPageLink": "Wyświetl wszystkie tagi",
"theme.tags.tagsPageTitle": "Tagi"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " por {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Última atualização {atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Marcadores:",
"theme.tags.tagsPageLink": "Ver todas os Marcadores",
"theme.tags.tagsPageTitle": "Marcadores"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " por {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Última atualização{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Tags:",
"theme.tags.tagsPageLink": "Ver todas as Tags",
"theme.tags.tagsPageTitle": "Tags"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " от {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Последнее обновление{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Перейти к главному меню",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Теги:",
"theme.tags.tagsPageLink": "Посмотреть все теги",
"theme.tags.tagsPageTitle": "Теги"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " {user} tarafından",
"theme.lastUpdated.lastUpdatedAtBy": "En son{atDate}{byUser} güncellendi",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Etiketler:",
"theme.tags.tagsPageLink": "Tüm Etiketleri Görüntüle",
"theme.tags.tagsPageTitle": "Etiketler"

View file

@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": " bởi {user}",
"theme.lastUpdated.lastUpdatedAtBy": "Cập nhật lần cuối{atDate}{byUser}",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← Back to main menu",
"theme.navbar.mobileVersionsDropdown.label": "Versions",
"theme.tags.tagsListLabel": "Thẻ:",
"theme.tags.tagsPageLink": "Xem tất cả Thẻ",
"theme.tags.tagsPageTitle": "Thẻ"

View file

@ -42,8 +42,8 @@
"theme.docs.sidebar.collapseButtonTitle": "收起侧边栏",
"theme.docs.sidebar.expandButtonAriaLabel": "展开侧边栏",
"theme.docs.sidebar.expandButtonTitle": "展开侧边栏",
"theme.docs.tagDocListPageTitle": "{nDocsTagged} with \"{tagName}\"",
"theme.docs.tagDocListPageTitle.nDocsTagged": "One doc tagged|{count} docs tagged",
"theme.docs.tagDocListPageTitle": "{nDocsTagged} 含有标签「{tagName}」",
"theme.docs.tagDocListPageTitle.nDocsTagged": "{count} 篇文档带有标签",
"theme.docs.versions.latestVersionLinkLabel": "最新版本",
"theme.docs.versions.latestVersionSuggestionLabel": "最新的文档请参阅 {latestVersionLink} ({versionLabel})。",
"theme.docs.versions.unmaintainedVersionLabel": "此为 {siteTitle} {versionLabel} 版的文档,现已不再积极维护。",
@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": "由 {user} ",
"theme.lastUpdated.lastUpdatedAtBy": "最后{byUser}{atDate}更新",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← 回到主菜单",
"theme.navbar.mobileVersionsDropdown.label": "选择版本",
"theme.tags.tagsListLabel": "标签:",
"theme.tags.tagsPageLink": "查看所有标签",
"theme.tags.tagsPageTitle": "标签"

View file

@ -42,8 +42,8 @@
"theme.docs.sidebar.collapseButtonTitle": "收起側邊欄",
"theme.docs.sidebar.expandButtonAriaLabel": "展開側邊欄",
"theme.docs.sidebar.expandButtonTitle": "展開側邊欄",
"theme.docs.tagDocListPageTitle": "{nDocsTagged} with \"{tagName}\"",
"theme.docs.tagDocListPageTitle.nDocsTagged": "One doc tagged|{count} docs tagged",
"theme.docs.tagDocListPageTitle": "{nDocsTagged} 含有標籤「{tagName}」",
"theme.docs.tagDocListPageTitle.nDocsTagged": "{count} 篇文件帶有標籤",
"theme.docs.versions.latestVersionLinkLabel": "最新版本",
"theme.docs.versions.latestVersionSuggestionLabel": "最新的文件請參閱 {latestVersionLink} ({versionLabel})。",
"theme.docs.versions.unmaintainedVersionLabel": "此為 {siteTitle} {versionLabel} 版的文件,現已不再積極維護。",
@ -52,6 +52,7 @@
"theme.lastUpdated.byUser": "由 {user} ",
"theme.lastUpdated.lastUpdatedAtBy": "最後{byUser}{atDate}更新",
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": "← 回到主菜單",
"theme.navbar.mobileVersionsDropdown.label": "選擇版本",
"theme.tags.tagsListLabel": "標籤:",
"theme.tags.tagsPageLink": "查看所有標籤",
"theme.tags.tagsPageTitle": "標籤"

View file

@ -15,6 +15,7 @@ import {
} from '@theme/hooks/useDocs';
import type {Props} from '@theme/NavbarItem/DocsVersionDropdownNavbarItem';
import {useDocsPreferredVersion} from '@docusaurus/theme-common';
import {translate} from '@docusaurus/Translate';
const getVersionMainDoc = (version) =>
version.docs.find((doc) => doc.id === version.mainDocId);
@ -62,7 +63,15 @@ export default function DocsVersionDropdownNavbarItem({
activeDocContext.activeVersion ?? preferredVersion ?? latestVersion;
// Mobile dropdown is handled a bit differently
const dropdownLabel = mobile && items ? 'Versions' : dropdownVersion.label;
const dropdownLabel =
mobile && items
? translate({
id: 'theme.navbar.mobileVersionsDropdown.label',
message: 'Versions',
description:
'The label for the navbar versions dropdown on mobile view',
})
: dropdownVersion.label;
const dropdownTo =
mobile && items ? undefined : getVersionMainDoc(dropdownVersion).path;

View file

@ -219,7 +219,7 @@ Read the [i18n introduction](../../i18n/i18n-introduction.md) first.
- **Base path**: `website/i18n/<locale>/docusaurus-plugin-content-blog`
- **Multi-instance path**: `website/i18n/<locale>/docusaurus-plugin-content-blog-<pluginId>`
- **JSON files**: N/A
- **JSON files**: extracted with [`docusaurus write-translations`](../../cli.md#docusaurus-write-translations-sitedir)
- **Markdown files**: `website/i18n/<locale>/docusaurus-plugin-content-blog`
### Example file-system structure {#example-file-system-structure}
@ -229,5 +229,8 @@ website/i18n/<locale>/docusaurus-plugin-content-blog
│ # translations for website/blog
├── first-blog-post.md
└── second-blog-post.md
├── second-blog-post.md
│ # translations for the plugin options that will be rendered
└── options.json
```