mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-06 10:20:09 +02:00
Add initial implementation of sidebar keys
This commit is contained in:
parent
222a077d85
commit
3a5010a83a
9 changed files with 349 additions and 34 deletions
|
@ -7,6 +7,7 @@
|
|||
|
||||
import _ from 'lodash';
|
||||
import {mergeTranslations} from '@docusaurus/utils';
|
||||
import logger from '@docusaurus/logger';
|
||||
import {CURRENT_VERSION_NAME} from './constants';
|
||||
import {
|
||||
collectSidebarCategories,
|
||||
|
@ -40,20 +41,50 @@ function getVersionFileName(versionName: string): string {
|
|||
return `version-${versionName}`;
|
||||
}
|
||||
|
||||
type TranslationMessageEntry = [string, TranslationMessage];
|
||||
|
||||
function ensureNoSidebarDuplicateEntries(
|
||||
translationEntries: TranslationMessageEntry[],
|
||||
): void {
|
||||
const grouped = _.groupBy(translationEntries, (entry) => entry[0]);
|
||||
const duplicates = Object.entries(grouped).filter(
|
||||
(entry) => entry[1].length > 1,
|
||||
);
|
||||
|
||||
if (duplicates.length > 0) {
|
||||
throw new Error(`Multiple docs sidebar items produce the same translation key.
|
||||
- ${duplicates
|
||||
.map(([translationKey, entries]) => {
|
||||
return `${translationKey}: ${
|
||||
entries.length
|
||||
} duplicates found:\n - ${entries
|
||||
.map((duplicate) => {
|
||||
return logger.interpolate`name=${duplicate[1].message} (subdue=${duplicate[1].description})}`;
|
||||
})
|
||||
.join('\n - ')}`;
|
||||
})
|
||||
.join('\n\n- ')}
|
||||
|
||||
To avoid translation key conflicts, use the ${logger.code(
|
||||
'key',
|
||||
)} attribute on the sidebar items above to uniquely identify them.
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
function getSidebarTranslationFileContent(
|
||||
sidebar: Sidebar,
|
||||
sidebarName: string,
|
||||
): TranslationFileContent {
|
||||
type TranslationMessageEntry = [string, TranslationMessage];
|
||||
|
||||
const categories = collectSidebarCategories(sidebar);
|
||||
|
||||
const categoryEntries: TranslationMessageEntry[] = categories.flatMap(
|
||||
(category) => {
|
||||
const entries: TranslationMessageEntry[] = [];
|
||||
const categoryKey = category.key ?? category.label;
|
||||
|
||||
entries.push([
|
||||
`sidebar.${sidebarName}.category.${category.label}`,
|
||||
`sidebar.${sidebarName}.category.${categoryKey}`,
|
||||
{
|
||||
message: category.label,
|
||||
description: `The label for category ${category.label} in sidebar ${sidebarName}`,
|
||||
|
@ -63,7 +94,7 @@ function getSidebarTranslationFileContent(
|
|||
if (category.link?.type === 'generated-index') {
|
||||
if (category.link.title) {
|
||||
entries.push([
|
||||
`sidebar.${sidebarName}.category.${category.label}.link.generated-index.title`,
|
||||
`sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.title`,
|
||||
{
|
||||
message: category.link.title,
|
||||
description: `The generated-index page title for category ${category.label} in sidebar ${sidebarName}`,
|
||||
|
@ -72,7 +103,7 @@ function getSidebarTranslationFileContent(
|
|||
}
|
||||
if (category.link.description) {
|
||||
entries.push([
|
||||
`sidebar.${sidebarName}.category.${category.label}.link.generated-index.description`,
|
||||
`sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.description`,
|
||||
{
|
||||
message: category.link.description,
|
||||
description: `The generated-index page description for category ${category.label} in sidebar ${sidebarName}`,
|
||||
|
@ -85,45 +116,37 @@ function getSidebarTranslationFileContent(
|
|||
},
|
||||
);
|
||||
|
||||
_.chain(categoryEntries)
|
||||
.groupBy((entry) => entry[0])
|
||||
.forEach((group, key) => {
|
||||
if (group.length > 1) {
|
||||
console.warn(`KEY CONFLICT FOR key = ${key}`, group.length);
|
||||
}
|
||||
})
|
||||
.value();
|
||||
|
||||
const categoryContent: TranslationFileContent =
|
||||
Object.fromEntries(categoryEntries);
|
||||
|
||||
const links = collectSidebarLinks(sidebar);
|
||||
const linksContent: TranslationFileContent = Object.fromEntries(
|
||||
links.map((link) => [
|
||||
`sidebar.${sidebarName}.link.${link.label}`,
|
||||
const linksEntries: TranslationMessageEntry[] = links.map((link) => {
|
||||
const linkKey = link.key ?? link.label;
|
||||
return [
|
||||
`sidebar.${sidebarName}.link.${linkKey}`,
|
||||
{
|
||||
message: link.label,
|
||||
description: `The label for link ${link.label} in sidebar ${sidebarName}, linking to ${link.href}`,
|
||||
},
|
||||
]),
|
||||
);
|
||||
];
|
||||
});
|
||||
|
||||
const docs = collectSidebarDocItems(sidebar)
|
||||
.concat(collectSidebarRefs(sidebar))
|
||||
.filter((item) => item.translatable);
|
||||
const docLinksContent: TranslationFileContent = Object.fromEntries(
|
||||
docs.map((doc) => [
|
||||
`sidebar.${sidebarName}.doc.${doc.label!}`,
|
||||
const docLinksEntries: TranslationMessageEntry[] = docs.map((doc) => {
|
||||
const docKey = doc.key ?? doc.label!;
|
||||
return [
|
||||
`sidebar.${sidebarName}.doc.${docKey}`,
|
||||
{
|
||||
message: doc.label!,
|
||||
description: `The label for the doc item ${doc.label!} in sidebar ${sidebarName}, linking to the doc ${
|
||||
doc.id
|
||||
}`,
|
||||
},
|
||||
]),
|
||||
);
|
||||
];
|
||||
});
|
||||
|
||||
return mergeTranslations([categoryContent, linksContent, docLinksContent]);
|
||||
const allEntries = [...categoryEntries, ...linksEntries, ...docLinksEntries];
|
||||
ensureNoSidebarDuplicateEntries(allEntries);
|
||||
return Object.fromEntries(allEntries);
|
||||
}
|
||||
|
||||
function translateSidebar({
|
||||
|
@ -162,27 +185,30 @@ function translateSidebar({
|
|||
return transformSidebarItems(sidebar, (item) => {
|
||||
if (item.type === 'category') {
|
||||
const link = transformSidebarCategoryLink(item);
|
||||
const categoryKey = item.key ?? item.label;
|
||||
return {
|
||||
...item,
|
||||
label:
|
||||
sidebarsTranslations[`sidebar.${sidebarName}.category.${item.label}`]
|
||||
sidebarsTranslations[`sidebar.${sidebarName}.category.${categoryKey}`]
|
||||
?.message ?? item.label,
|
||||
...(link && {link}),
|
||||
};
|
||||
}
|
||||
if (item.type === 'link') {
|
||||
const linkKey = item.key ?? item.label;
|
||||
return {
|
||||
...item,
|
||||
label:
|
||||
sidebarsTranslations[`sidebar.${sidebarName}.link.${item.label}`]
|
||||
sidebarsTranslations[`sidebar.${sidebarName}.link.${linkKey}`]
|
||||
?.message ?? item.label,
|
||||
};
|
||||
}
|
||||
if ((item.type === 'doc' || item.type === 'ref') && item.translatable) {
|
||||
const docKey = item.key ?? item.label!;
|
||||
return {
|
||||
...item,
|
||||
label:
|
||||
sidebarsTranslations[`sidebar.${sidebarName}.doc.${item.label!}`]
|
||||
sidebarsTranslations[`sidebar.${sidebarName}.doc.${docKey}`]
|
||||
?.message ?? item.label,
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue