@docusaurus/plugin-content-docs 3.9.1 → 3.9.2-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client/docsUtils.js +12 -5
- package/lib/docs.js +2 -2
- package/lib/frontMatter.js +1 -0
- package/lib/index.js +1 -1
- package/lib/sidebars/generator.js +5 -2
- package/lib/translations.js +52 -9
- package/package.json +11 -11
- package/src/client/docsUtils.tsx +14 -7
- package/src/docs.ts +2 -0
- package/src/frontMatter.ts +1 -0
- package/src/index.ts +1 -2
- package/src/plugin-content-docs.d.ts +9 -1
- package/src/sidebars/generator.ts +7 -1
- package/src/translations.ts +67 -9
package/lib/client/docsUtils.js
CHANGED
|
@@ -148,11 +148,18 @@ function getSidebarBreadcrumbs({ sidebarItems, pathname, onlyCategories = false,
|
|
|
148
148
|
const breadcrumbs = [];
|
|
149
149
|
function extract(items) {
|
|
150
150
|
for (const item of items) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
(
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
// Extract category item
|
|
152
|
+
if (item.type === 'category') {
|
|
153
|
+
if (isSamePath(item.href, pathname) || extract(item.items)) {
|
|
154
|
+
breadcrumbs.unshift(item);
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Extract doc item
|
|
159
|
+
else if (item.type === 'link' &&
|
|
160
|
+
item.docId &&
|
|
161
|
+
isSamePath(item.href, pathname)) {
|
|
162
|
+
if (!onlyCategories) {
|
|
156
163
|
breadcrumbs.unshift(item);
|
|
157
164
|
}
|
|
158
165
|
return true;
|
package/lib/docs.js
CHANGED
|
@@ -38,7 +38,7 @@ async function readVersionDocs(versionMetadata, options) {
|
|
|
38
38
|
}
|
|
39
39
|
async function doProcessDocMetadata({ docFile, versionMetadata, context, options, env, tagsFile, }) {
|
|
40
40
|
const { source, content, contentPath, filePath } = docFile;
|
|
41
|
-
const { siteDir, siteConfig: { markdown: { parseFrontMatter }, }, } = context;
|
|
41
|
+
const { siteDir, siteConfig: { markdown: { parseFrontMatter }, future: { experimental_vcs: vcs }, }, } = context;
|
|
42
42
|
const { frontMatter: unsafeFrontMatter, contentTitle, excerpt, } = await (0, utils_1.parseMarkdownFile)({
|
|
43
43
|
filePath,
|
|
44
44
|
fileContent: content,
|
|
@@ -50,7 +50,7 @@ async function doProcessDocMetadata({ docFile, versionMetadata, context, options
|
|
|
50
50
|
// (01-MyFolder/01-MyDoc.md => MyFolder/MyDoc)
|
|
51
51
|
// but allow to disable this behavior with front matter
|
|
52
52
|
parse_number_prefixes: parseNumberPrefixes = true, last_update: lastUpdateFrontMatter, } = frontMatter;
|
|
53
|
-
const lastUpdate = await (0, utils_1.readLastUpdateData)(filePath, options, lastUpdateFrontMatter);
|
|
53
|
+
const lastUpdate = await (0, utils_1.readLastUpdateData)(filePath, options, lastUpdateFrontMatter, vcs);
|
|
54
54
|
// E.g. api/plugins/myDoc -> myDoc; myDoc -> myDoc
|
|
55
55
|
const sourceFileNameWithoutExtension = path_1.default.basename(source, path_1.default.extname(source));
|
|
56
56
|
// E.g. api/plugins/myDoc -> api/plugins; myDoc -> .
|
package/lib/frontMatter.js
CHANGED
|
@@ -24,6 +24,7 @@ exports.DocFrontMatterSchema = utils_validation_1.JoiFrontMatter.object({
|
|
|
24
24
|
// See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
|
|
25
25
|
description: utils_validation_1.JoiFrontMatter.string().allow(''),
|
|
26
26
|
slug: utils_validation_1.JoiFrontMatter.string(),
|
|
27
|
+
sidebar_key: utils_validation_1.JoiFrontMatter.string(),
|
|
27
28
|
sidebar_label: utils_validation_1.JoiFrontMatter.string(),
|
|
28
29
|
sidebar_position: utils_validation_1.JoiFrontMatter.number(),
|
|
29
30
|
sidebar_class_name: utils_validation_1.JoiFrontMatter.string(),
|
package/lib/index.js
CHANGED
|
@@ -75,7 +75,7 @@ async function pluginContentDocs(context, options) {
|
|
|
75
75
|
versionsMetadata,
|
|
76
76
|
}),
|
|
77
77
|
].filter((d) => typeof d === 'string'),
|
|
78
|
-
useCrossCompilerCache: siteConfig.future.
|
|
78
|
+
useCrossCompilerCache: siteConfig.future.faster.mdxCrossCompilerCache,
|
|
79
79
|
admonitions: options.admonitions,
|
|
80
80
|
remarkPlugins,
|
|
81
81
|
rehypePlugins,
|
|
@@ -91,7 +91,7 @@ Available doc IDs:
|
|
|
91
91
|
*/
|
|
92
92
|
function generateSidebar(fsModel) {
|
|
93
93
|
function createDocItem(id, fullPath, fileName) {
|
|
94
|
-
const { sidebarPosition: position, frontMatter: { sidebar_label: label, sidebar_class_name: className, sidebar_custom_props: customProps, }, } = getDoc(id);
|
|
94
|
+
const { sidebarPosition: position, frontMatter: { sidebar_key: key, sidebar_label: label, sidebar_class_name: className, sidebar_custom_props: customProps, }, } = getDoc(id);
|
|
95
95
|
return {
|
|
96
96
|
type: 'doc',
|
|
97
97
|
id,
|
|
@@ -99,6 +99,7 @@ Available doc IDs:
|
|
|
99
99
|
source: fileName,
|
|
100
100
|
// We don't want these fields to magically appear in the generated
|
|
101
101
|
// sidebar
|
|
102
|
+
...(key !== undefined && { key }),
|
|
102
103
|
...(label !== undefined && { label }),
|
|
103
104
|
...(className !== undefined && { className }),
|
|
104
105
|
...(customProps !== undefined && { customProps }),
|
|
@@ -139,6 +140,7 @@ Available doc IDs:
|
|
|
139
140
|
return {
|
|
140
141
|
id,
|
|
141
142
|
position: doc.sidebarPosition,
|
|
143
|
+
key: doc.frontMatter.sidebar_key,
|
|
142
144
|
label: doc.frontMatter.sidebar_label ?? doc.title,
|
|
143
145
|
customProps: doc.frontMatter.sidebar_custom_props,
|
|
144
146
|
className: doc.frontMatter.sidebar_class_name,
|
|
@@ -156,6 +158,7 @@ Available doc IDs:
|
|
|
156
158
|
const className = categoryMetadata?.className ?? categoryLinkedDoc?.className;
|
|
157
159
|
const customProps = categoryMetadata?.customProps ?? categoryLinkedDoc?.customProps;
|
|
158
160
|
const { filename, numberPrefix } = numberPrefixParser(folderName);
|
|
161
|
+
const key = categoryMetadata?.key ?? categoryLinkedDoc?.key;
|
|
159
162
|
return {
|
|
160
163
|
type: 'category',
|
|
161
164
|
label: categoryMetadata?.label ?? categoryLinkedDoc?.label ?? filename,
|
|
@@ -171,7 +174,7 @@ Available doc IDs:
|
|
|
171
174
|
...(categoryMetadata?.description && {
|
|
172
175
|
description: categoryMetadata?.description,
|
|
173
176
|
}),
|
|
174
|
-
...(
|
|
177
|
+
...(key && { key }),
|
|
175
178
|
...(link && { link }),
|
|
176
179
|
};
|
|
177
180
|
}
|
package/lib/translations.js
CHANGED
|
@@ -39,7 +39,10 @@ function ensureNoSidebarDuplicateEntries(translationEntries) {
|
|
|
39
39
|
.join('\n\n- ')}
|
|
40
40
|
|
|
41
41
|
To avoid translation key conflicts, use the ${logger_1.default.code('key')} attribute on the sidebar items above to uniquely identify them.
|
|
42
|
-
|
|
42
|
+
|
|
43
|
+
When using autogenerated sidebars, you can provide a unique translation key by adding:
|
|
44
|
+
- the ${logger_1.default.code('key')} attribute to category item metadata (${logger_1.default.code('_category_.json')} / ${logger_1.default.code('_category_.yml')})
|
|
45
|
+
- the ${logger_1.default.code('sidebar_key')} attribute to doc item metadata (front matter in ${logger_1.default.code('Category/index.mdx')})`);
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
48
|
function getSidebarTranslationFileContent(sidebar, sidebarName) {
|
|
@@ -51,7 +54,7 @@ function getSidebarTranslationFileContent(sidebar, sidebarName) {
|
|
|
51
54
|
`sidebar.${sidebarName}.category.${categoryKey}`,
|
|
52
55
|
{
|
|
53
56
|
message: category.label,
|
|
54
|
-
description: `The label for category ${category.label} in sidebar ${sidebarName}`,
|
|
57
|
+
description: `The label for category '${category.label}' in sidebar '${sidebarName}'`,
|
|
55
58
|
},
|
|
56
59
|
]);
|
|
57
60
|
if (category.link?.type === 'generated-index') {
|
|
@@ -60,7 +63,7 @@ function getSidebarTranslationFileContent(sidebar, sidebarName) {
|
|
|
60
63
|
`sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.title`,
|
|
61
64
|
{
|
|
62
65
|
message: category.link.title,
|
|
63
|
-
description: `The generated-index page title for category ${category.label} in sidebar ${sidebarName}`,
|
|
66
|
+
description: `The generated-index page title for category '${category.label}' in sidebar '${sidebarName}'`,
|
|
64
67
|
},
|
|
65
68
|
]);
|
|
66
69
|
}
|
|
@@ -69,7 +72,7 @@ function getSidebarTranslationFileContent(sidebar, sidebarName) {
|
|
|
69
72
|
`sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.description`,
|
|
70
73
|
{
|
|
71
74
|
message: category.link.description,
|
|
72
|
-
description: `The generated-index page description for category ${category.label} in sidebar ${sidebarName}`,
|
|
75
|
+
description: `The generated-index page description for category '${category.label}' in sidebar '${sidebarName}'`,
|
|
73
76
|
},
|
|
74
77
|
]);
|
|
75
78
|
}
|
|
@@ -83,7 +86,7 @@ function getSidebarTranslationFileContent(sidebar, sidebarName) {
|
|
|
83
86
|
`sidebar.${sidebarName}.link.${linkKey}`,
|
|
84
87
|
{
|
|
85
88
|
message: link.label,
|
|
86
|
-
description: `The label for link ${link.label} in sidebar ${sidebarName}, linking to ${link.href}`,
|
|
89
|
+
description: `The label for link '${link.label}' in sidebar '${sidebarName}', linking to '${link.href}'`,
|
|
87
90
|
},
|
|
88
91
|
];
|
|
89
92
|
});
|
|
@@ -96,7 +99,7 @@ function getSidebarTranslationFileContent(sidebar, sidebarName) {
|
|
|
96
99
|
`sidebar.${sidebarName}.doc.${docKey}`,
|
|
97
100
|
{
|
|
98
101
|
message: doc.label,
|
|
99
|
-
description: `The label for the doc item ${doc.label} in sidebar ${sidebarName}, linking to the doc ${doc.id}`,
|
|
102
|
+
description: `The label for the doc item '${doc.label}' in sidebar '${sidebarName}', linking to the doc ${doc.id}`,
|
|
100
103
|
},
|
|
101
104
|
];
|
|
102
105
|
});
|
|
@@ -110,8 +113,9 @@ function translateSidebar({ sidebar, sidebarName, sidebarsTranslations, }) {
|
|
|
110
113
|
return undefined;
|
|
111
114
|
}
|
|
112
115
|
if (category.link.type === 'generated-index') {
|
|
113
|
-
const
|
|
114
|
-
const
|
|
116
|
+
const categoryKey = category.key ?? category.label;
|
|
117
|
+
const title = sidebarsTranslations[`sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.title`]?.message ?? category.link.title;
|
|
118
|
+
const description = sidebarsTranslations[`sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.description`]?.message ?? category.link.description;
|
|
115
119
|
return {
|
|
116
120
|
...category.link,
|
|
117
121
|
title,
|
|
@@ -175,12 +179,51 @@ function getVersionTranslationFiles(version) {
|
|
|
175
179
|
},
|
|
176
180
|
];
|
|
177
181
|
}
|
|
182
|
+
// TODO Docusaurus v4 or later
|
|
183
|
+
// this temporarily works, but it is not an ideal solution
|
|
184
|
+
// The docs navigation can be computed and shouldn't be part of LoadedVersion
|
|
185
|
+
// We need to derive the navigation from already translated content
|
|
186
|
+
// See https://github.com/facebook/docusaurus/pull/11794
|
|
187
|
+
function translateDocNavigation(docs, translatedSidebars) {
|
|
188
|
+
// Build a map of permalink -> translated label for generated-index categories
|
|
189
|
+
const translatedLabelByPermalink = new Map();
|
|
190
|
+
for (const sidebar of Object.values(translatedSidebars)) {
|
|
191
|
+
for (const category of (0, utils_2.collectSidebarCategories)(sidebar)) {
|
|
192
|
+
if (category.link?.type === 'generated-index') {
|
|
193
|
+
translatedLabelByPermalink.set(category.link.permalink, category.label);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (translatedLabelByPermalink.size === 0) {
|
|
198
|
+
return docs;
|
|
199
|
+
}
|
|
200
|
+
return docs.map((doc) => {
|
|
201
|
+
const previous = doc.previous && translatedLabelByPermalink.has(doc.previous.permalink)
|
|
202
|
+
? {
|
|
203
|
+
...doc.previous,
|
|
204
|
+
title: translatedLabelByPermalink.get(doc.previous.permalink),
|
|
205
|
+
}
|
|
206
|
+
: doc.previous;
|
|
207
|
+
const next = doc.next && translatedLabelByPermalink.has(doc.next.permalink)
|
|
208
|
+
? {
|
|
209
|
+
...doc.next,
|
|
210
|
+
title: translatedLabelByPermalink.get(doc.next.permalink),
|
|
211
|
+
}
|
|
212
|
+
: doc.next;
|
|
213
|
+
if (previous === doc.previous && next === doc.next) {
|
|
214
|
+
return doc;
|
|
215
|
+
}
|
|
216
|
+
return { ...doc, previous, next };
|
|
217
|
+
});
|
|
218
|
+
}
|
|
178
219
|
function translateVersion(version, translationFiles) {
|
|
179
220
|
const versionTranslations = translationFiles[getVersionFileName(version.versionName)].content;
|
|
221
|
+
const translatedSidebars = translateSidebars(version, versionTranslations);
|
|
180
222
|
return {
|
|
181
223
|
...version,
|
|
182
224
|
label: versionTranslations['version.label']?.message ?? version.label,
|
|
183
|
-
sidebars:
|
|
225
|
+
sidebars: translatedSidebars,
|
|
226
|
+
docs: translateDocNavigation(version.docs, translatedSidebars),
|
|
184
227
|
};
|
|
185
228
|
}
|
|
186
229
|
function getVersionsTranslationFiles(versions) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docusaurus/plugin-content-docs",
|
|
3
|
-
"version": "3.9.
|
|
3
|
+
"version": "3.9.2-alpha.0",
|
|
4
4
|
"description": "Docs plugin for Docusaurus.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -35,15 +35,15 @@
|
|
|
35
35
|
},
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@docusaurus/core": "3.9.
|
|
39
|
-
"@docusaurus/logger": "3.9.
|
|
40
|
-
"@docusaurus/mdx-loader": "3.9.
|
|
41
|
-
"@docusaurus/module-type-aliases": "3.9.
|
|
42
|
-
"@docusaurus/theme-common": "3.9.
|
|
43
|
-
"@docusaurus/types": "3.9.
|
|
44
|
-
"@docusaurus/utils": "3.9.
|
|
45
|
-
"@docusaurus/utils-common": "3.9.
|
|
46
|
-
"@docusaurus/utils-validation": "3.9.
|
|
38
|
+
"@docusaurus/core": "3.9.2-alpha.0",
|
|
39
|
+
"@docusaurus/logger": "3.9.2-alpha.0",
|
|
40
|
+
"@docusaurus/mdx-loader": "3.9.2-alpha.0",
|
|
41
|
+
"@docusaurus/module-type-aliases": "3.9.2-alpha.0",
|
|
42
|
+
"@docusaurus/theme-common": "3.9.2-alpha.0",
|
|
43
|
+
"@docusaurus/types": "3.9.2-alpha.0",
|
|
44
|
+
"@docusaurus/utils": "3.9.2-alpha.0",
|
|
45
|
+
"@docusaurus/utils-common": "3.9.2-alpha.0",
|
|
46
|
+
"@docusaurus/utils-validation": "3.9.2-alpha.0",
|
|
47
47
|
"@types/react-router-config": "^5.0.7",
|
|
48
48
|
"combine-promises": "^1.1.0",
|
|
49
49
|
"fs-extra": "^11.1.1",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"engines": {
|
|
68
68
|
"node": ">=20.0"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "27626cdd7a102277935f10cc4d8d3f93e211eafe"
|
|
71
71
|
}
|
package/src/client/docsUtils.tsx
CHANGED
|
@@ -234,15 +234,22 @@ function getSidebarBreadcrumbs({
|
|
|
234
234
|
}): PropSidebarBreadcrumbsItem[] {
|
|
235
235
|
const breadcrumbs: PropSidebarBreadcrumbsItem[] = [];
|
|
236
236
|
|
|
237
|
-
function extract(items: PropSidebarItem[]) {
|
|
237
|
+
function extract(items: PropSidebarItem[]): boolean {
|
|
238
238
|
for (const item of items) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
239
|
+
// Extract category item
|
|
240
|
+
if (item.type === 'category') {
|
|
241
|
+
if (isSamePath(item.href, pathname) || extract(item.items)) {
|
|
242
|
+
breadcrumbs.unshift(item);
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// Extract doc item
|
|
247
|
+
else if (
|
|
248
|
+
item.type === 'link' &&
|
|
249
|
+
item.docId &&
|
|
250
|
+
isSamePath(item.href, pathname)
|
|
243
251
|
) {
|
|
244
|
-
|
|
245
|
-
if (!filtered) {
|
|
252
|
+
if (!onlyCategories) {
|
|
246
253
|
breadcrumbs.unshift(item);
|
|
247
254
|
}
|
|
248
255
|
return true;
|
package/src/docs.ts
CHANGED
|
@@ -97,6 +97,7 @@ async function doProcessDocMetadata({
|
|
|
97
97
|
siteDir,
|
|
98
98
|
siteConfig: {
|
|
99
99
|
markdown: {parseFrontMatter},
|
|
100
|
+
future: {experimental_vcs: vcs},
|
|
100
101
|
},
|
|
101
102
|
} = context;
|
|
102
103
|
|
|
@@ -125,6 +126,7 @@ async function doProcessDocMetadata({
|
|
|
125
126
|
filePath,
|
|
126
127
|
options,
|
|
127
128
|
lastUpdateFrontMatter,
|
|
129
|
+
vcs,
|
|
128
130
|
);
|
|
129
131
|
|
|
130
132
|
// E.g. api/plugins/myDoc -> myDoc; myDoc -> myDoc
|
package/src/frontMatter.ts
CHANGED
|
@@ -30,6 +30,7 @@ export const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
|
|
|
30
30
|
// See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
|
|
31
31
|
description: Joi.string().allow(''),
|
|
32
32
|
slug: Joi.string(),
|
|
33
|
+
sidebar_key: Joi.string(),
|
|
33
34
|
sidebar_label: Joi.string(),
|
|
34
35
|
sidebar_position: Joi.number(),
|
|
35
36
|
sidebar_class_name: Joi.string(),
|
package/src/index.ts
CHANGED
|
@@ -131,8 +131,7 @@ export default async function pluginContentDocs(
|
|
|
131
131
|
}),
|
|
132
132
|
].filter((d): d is string => typeof d === 'string'),
|
|
133
133
|
|
|
134
|
-
useCrossCompilerCache:
|
|
135
|
-
siteConfig.future.experimental_faster.mdxCrossCompilerCache,
|
|
134
|
+
useCrossCompilerCache: siteConfig.future.faster.mdxCrossCompilerCache,
|
|
136
135
|
admonitions: options.admonitions,
|
|
137
136
|
remarkPlugins,
|
|
138
137
|
rehypePlugins,
|
|
@@ -339,7 +339,15 @@ declare module '@docusaurus/plugin-content-docs' {
|
|
|
339
339
|
* @see {@link DocMetadata.slug}
|
|
340
340
|
*/
|
|
341
341
|
slug?: string;
|
|
342
|
-
/**
|
|
342
|
+
/**
|
|
343
|
+
* Customizes the sidebar key for this doc,
|
|
344
|
+
* to uniquely identify it in translations.
|
|
345
|
+
*/
|
|
346
|
+
sidebar_key?: string;
|
|
347
|
+
/**
|
|
348
|
+
* Customizes the sidebar label for this doc.
|
|
349
|
+
* Will default to its title.
|
|
350
|
+
*/
|
|
343
351
|
sidebar_label?: string;
|
|
344
352
|
/**
|
|
345
353
|
* Controls the position of a doc inside the generated sidebar slice when
|
|
@@ -139,6 +139,7 @@ Available doc IDs:
|
|
|
139
139
|
const {
|
|
140
140
|
sidebarPosition: position,
|
|
141
141
|
frontMatter: {
|
|
142
|
+
sidebar_key: key,
|
|
142
143
|
sidebar_label: label,
|
|
143
144
|
sidebar_class_name: className,
|
|
144
145
|
sidebar_custom_props: customProps,
|
|
@@ -151,6 +152,7 @@ Available doc IDs:
|
|
|
151
152
|
source: fileName,
|
|
152
153
|
// We don't want these fields to magically appear in the generated
|
|
153
154
|
// sidebar
|
|
155
|
+
...(key !== undefined && {key}),
|
|
154
156
|
...(label !== undefined && {label}),
|
|
155
157
|
...(className !== undefined && {className}),
|
|
156
158
|
...(customProps !== undefined && {customProps}),
|
|
@@ -191,6 +193,7 @@ Available doc IDs:
|
|
|
191
193
|
function getCategoryLinkedDocMetadata():
|
|
192
194
|
| {
|
|
193
195
|
id: string;
|
|
196
|
+
key?: string;
|
|
194
197
|
position?: number;
|
|
195
198
|
label?: string;
|
|
196
199
|
customProps?: {[key: string]: unknown};
|
|
@@ -212,6 +215,7 @@ Available doc IDs:
|
|
|
212
215
|
return {
|
|
213
216
|
id,
|
|
214
217
|
position: doc.sidebarPosition,
|
|
218
|
+
key: doc.frontMatter.sidebar_key,
|
|
215
219
|
label: doc.frontMatter.sidebar_label ?? doc.title,
|
|
216
220
|
customProps: doc.frontMatter.sidebar_custom_props,
|
|
217
221
|
className: doc.frontMatter.sidebar_class_name,
|
|
@@ -236,6 +240,8 @@ Available doc IDs:
|
|
|
236
240
|
categoryMetadata?.customProps ?? categoryLinkedDoc?.customProps;
|
|
237
241
|
const {filename, numberPrefix} = numberPrefixParser(folderName);
|
|
238
242
|
|
|
243
|
+
const key = categoryMetadata?.key ?? categoryLinkedDoc?.key;
|
|
244
|
+
|
|
239
245
|
return {
|
|
240
246
|
type: 'category',
|
|
241
247
|
label: categoryMetadata?.label ?? categoryLinkedDoc?.label ?? filename,
|
|
@@ -252,7 +258,7 @@ Available doc IDs:
|
|
|
252
258
|
...(categoryMetadata?.description && {
|
|
253
259
|
description: categoryMetadata?.description,
|
|
254
260
|
}),
|
|
255
|
-
...(
|
|
261
|
+
...(key && {key}),
|
|
256
262
|
...(link && {link}),
|
|
257
263
|
};
|
|
258
264
|
}
|
package/src/translations.ts
CHANGED
|
@@ -71,7 +71,16 @@ function ensureNoSidebarDuplicateEntries(
|
|
|
71
71
|
To avoid translation key conflicts, use the ${logger.code(
|
|
72
72
|
'key',
|
|
73
73
|
)} attribute on the sidebar items above to uniquely identify them.
|
|
74
|
-
|
|
74
|
+
|
|
75
|
+
When using autogenerated sidebars, you can provide a unique translation key by adding:
|
|
76
|
+
- the ${logger.code('key')} attribute to category item metadata (${logger.code(
|
|
77
|
+
'_category_.json',
|
|
78
|
+
)} / ${logger.code('_category_.yml')})
|
|
79
|
+
- the ${logger.code(
|
|
80
|
+
'sidebar_key',
|
|
81
|
+
)} attribute to doc item metadata (front matter in ${logger.code(
|
|
82
|
+
'Category/index.mdx',
|
|
83
|
+
)})`);
|
|
75
84
|
}
|
|
76
85
|
}
|
|
77
86
|
|
|
@@ -90,7 +99,7 @@ function getSidebarTranslationFileContent(
|
|
|
90
99
|
`sidebar.${sidebarName}.category.${categoryKey}`,
|
|
91
100
|
{
|
|
92
101
|
message: category.label,
|
|
93
|
-
description: `The label for category ${category.label} in sidebar ${sidebarName}`,
|
|
102
|
+
description: `The label for category '${category.label}' in sidebar '${sidebarName}'`,
|
|
94
103
|
},
|
|
95
104
|
]);
|
|
96
105
|
|
|
@@ -100,7 +109,7 @@ function getSidebarTranslationFileContent(
|
|
|
100
109
|
`sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.title`,
|
|
101
110
|
{
|
|
102
111
|
message: category.link.title,
|
|
103
|
-
description: `The generated-index page title for category ${category.label} in sidebar ${sidebarName}`,
|
|
112
|
+
description: `The generated-index page title for category '${category.label}' in sidebar '${sidebarName}'`,
|
|
104
113
|
},
|
|
105
114
|
]);
|
|
106
115
|
}
|
|
@@ -109,7 +118,7 @@ function getSidebarTranslationFileContent(
|
|
|
109
118
|
`sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.description`,
|
|
110
119
|
{
|
|
111
120
|
message: category.link.description,
|
|
112
|
-
description: `The generated-index page description for category ${category.label} in sidebar ${sidebarName}`,
|
|
121
|
+
description: `The generated-index page description for category '${category.label}' in sidebar '${sidebarName}'`,
|
|
113
122
|
},
|
|
114
123
|
]);
|
|
115
124
|
}
|
|
@@ -126,7 +135,7 @@ function getSidebarTranslationFileContent(
|
|
|
126
135
|
`sidebar.${sidebarName}.link.${linkKey}`,
|
|
127
136
|
{
|
|
128
137
|
message: link.label,
|
|
129
|
-
description: `The label for link ${link.label} in sidebar ${sidebarName}, linking to ${link.href}`,
|
|
138
|
+
description: `The label for link '${link.label}' in sidebar '${sidebarName}', linking to '${link.href}'`,
|
|
130
139
|
},
|
|
131
140
|
];
|
|
132
141
|
});
|
|
@@ -140,7 +149,7 @@ function getSidebarTranslationFileContent(
|
|
|
140
149
|
`sidebar.${sidebarName}.doc.${docKey}`,
|
|
141
150
|
{
|
|
142
151
|
message: doc.label!,
|
|
143
|
-
description: `The label for the doc item ${doc.label!} in sidebar ${sidebarName}, linking to the doc ${
|
|
152
|
+
description: `The label for the doc item '${doc.label!}' in sidebar '${sidebarName}', linking to the doc ${
|
|
144
153
|
doc.id
|
|
145
154
|
}`,
|
|
146
155
|
},
|
|
@@ -168,13 +177,14 @@ function translateSidebar({
|
|
|
168
177
|
return undefined;
|
|
169
178
|
}
|
|
170
179
|
if (category.link.type === 'generated-index') {
|
|
180
|
+
const categoryKey = category.key ?? category.label;
|
|
171
181
|
const title =
|
|
172
182
|
sidebarsTranslations[
|
|
173
|
-
`sidebar.${sidebarName}.category.${
|
|
183
|
+
`sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.title`
|
|
174
184
|
]?.message ?? category.link.title;
|
|
175
185
|
const description =
|
|
176
186
|
sidebarsTranslations[
|
|
177
|
-
`sidebar.${sidebarName}.category.${
|
|
187
|
+
`sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.description`
|
|
178
188
|
]?.message ?? category.link.description;
|
|
179
189
|
return {
|
|
180
190
|
...category.link,
|
|
@@ -259,16 +269,64 @@ function getVersionTranslationFiles(version: LoadedVersion): TranslationFile[] {
|
|
|
259
269
|
},
|
|
260
270
|
];
|
|
261
271
|
}
|
|
272
|
+
|
|
273
|
+
// TODO Docusaurus v4 or later
|
|
274
|
+
// this temporarily works, but it is not an ideal solution
|
|
275
|
+
// The docs navigation can be computed and shouldn't be part of LoadedVersion
|
|
276
|
+
// We need to derive the navigation from already translated content
|
|
277
|
+
// See https://github.com/facebook/docusaurus/pull/11794
|
|
278
|
+
function translateDocNavigation(
|
|
279
|
+
docs: LoadedVersion['docs'],
|
|
280
|
+
translatedSidebars: Sidebars,
|
|
281
|
+
): LoadedVersion['docs'] {
|
|
282
|
+
// Build a map of permalink -> translated label for generated-index categories
|
|
283
|
+
const translatedLabelByPermalink = new Map<string, string>();
|
|
284
|
+
for (const sidebar of Object.values(translatedSidebars)) {
|
|
285
|
+
for (const category of collectSidebarCategories(sidebar)) {
|
|
286
|
+
if (category.link?.type === 'generated-index') {
|
|
287
|
+
translatedLabelByPermalink.set(category.link.permalink, category.label);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (translatedLabelByPermalink.size === 0) {
|
|
293
|
+
return docs;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return docs.map((doc) => {
|
|
297
|
+
const previous =
|
|
298
|
+
doc.previous && translatedLabelByPermalink.has(doc.previous.permalink)
|
|
299
|
+
? {
|
|
300
|
+
...doc.previous,
|
|
301
|
+
title: translatedLabelByPermalink.get(doc.previous.permalink)!,
|
|
302
|
+
}
|
|
303
|
+
: doc.previous;
|
|
304
|
+
const next =
|
|
305
|
+
doc.next && translatedLabelByPermalink.has(doc.next.permalink)
|
|
306
|
+
? {
|
|
307
|
+
...doc.next,
|
|
308
|
+
title: translatedLabelByPermalink.get(doc.next.permalink)!,
|
|
309
|
+
}
|
|
310
|
+
: doc.next;
|
|
311
|
+
if (previous === doc.previous && next === doc.next) {
|
|
312
|
+
return doc;
|
|
313
|
+
}
|
|
314
|
+
return {...doc, previous, next};
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
|
|
262
318
|
function translateVersion(
|
|
263
319
|
version: LoadedVersion,
|
|
264
320
|
translationFiles: {[fileName: string]: TranslationFile},
|
|
265
321
|
): LoadedVersion {
|
|
266
322
|
const versionTranslations =
|
|
267
323
|
translationFiles[getVersionFileName(version.versionName)]!.content;
|
|
324
|
+
const translatedSidebars = translateSidebars(version, versionTranslations);
|
|
268
325
|
return {
|
|
269
326
|
...version,
|
|
270
327
|
label: versionTranslations['version.label']?.message ?? version.label,
|
|
271
|
-
sidebars:
|
|
328
|
+
sidebars: translatedSidebars,
|
|
329
|
+
docs: translateDocNavigation(version.docs, translatedSidebars),
|
|
272
330
|
};
|
|
273
331
|
}
|
|
274
332
|
|