mirror of
https://github.com/facebook/docusaurus.git
synced 2025-07-19 09:37:43 +02:00
infer translate from presence of translation dir
This commit is contained in:
parent
5cfe2c1dca
commit
fe7dba95a8
7 changed files with 91 additions and 57 deletions
5
packages/docusaurus-types/src/i18n.d.ts
vendored
5
packages/docusaurus-types/src/i18n.d.ts
vendored
|
@ -33,9 +33,8 @@ export type I18nLocaleConfig = {
|
|||
*/
|
||||
path: string;
|
||||
/**
|
||||
* Should we run the extra translation process for this locale?
|
||||
* By default, we skip the translation process for the default locale,
|
||||
* while all the other locales run it.
|
||||
* Should we attempt to translate this locale?
|
||||
* By default, it will only be run if the `./i18n/<locale>` exists.
|
||||
*/
|
||||
translate: boolean;
|
||||
};
|
||||
|
|
|
@ -91,7 +91,11 @@ async function getLocalesToBuild({
|
|||
localizePath,
|
||||
});
|
||||
|
||||
const i18n = await loadI18n(context.siteConfig);
|
||||
const i18n = await loadI18n({
|
||||
siteDir,
|
||||
config: context.siteConfig,
|
||||
currentLocale: context.siteConfig.i18n.defaultLocale // Awkward but ok
|
||||
});
|
||||
|
||||
const locales = cliOptions.locale ?? i18n.locales;
|
||||
|
||||
|
|
1
packages/docusaurus/src/server/__tests__/__fixtures__/load-i18n-site/i18n/de/README.md
generated
Normal file
1
packages/docusaurus/src/server/__tests__/__fixtures__/load-i18n-site/i18n/de/README.md
generated
Normal file
|
@ -0,0 +1 @@
|
|||
Since i18n/de folder exists, de locale should infer to translate = true
|
1
packages/docusaurus/src/server/__tests__/__fixtures__/load-i18n-site/i18n/fr/README.md
generated
Normal file
1
packages/docusaurus/src/server/__tests__/__fixtures__/load-i18n-site/i18n/fr/README.md
generated
Normal file
|
@ -0,0 +1 @@
|
|||
Since i18n/fr folder exists, fr locale should infer to translate = true
|
|
@ -6,17 +6,33 @@
|
|||
*/
|
||||
|
||||
import {jest} from '@jest/globals';
|
||||
import path from 'path';
|
||||
import {loadI18n, getDefaultLocaleConfig} from '../i18n';
|
||||
import {DEFAULT_I18N_CONFIG} from '../configValidation';
|
||||
import type {DocusaurusConfig, I18nConfig} from '@docusaurus/types';
|
||||
|
||||
function loadI18nTest(i18nConfig: I18nConfig, locale?: string) {
|
||||
return loadI18n(
|
||||
{
|
||||
const loadI18nSiteDir = path.resolve(
|
||||
__dirname,
|
||||
'__fixtures__',
|
||||
'load-i18n-site',
|
||||
);
|
||||
|
||||
function loadI18nTest({
|
||||
siteDir = loadI18nSiteDir,
|
||||
i18nConfig,
|
||||
currentLocale,
|
||||
}: {
|
||||
siteDir?: string;
|
||||
i18nConfig: I18nConfig;
|
||||
currentLocale: string;
|
||||
}) {
|
||||
return loadI18n({
|
||||
siteDir,
|
||||
config: {
|
||||
i18n: i18nConfig,
|
||||
} as DocusaurusConfig,
|
||||
{locale},
|
||||
);
|
||||
currentLocale,
|
||||
});
|
||||
}
|
||||
|
||||
describe('defaultLocaleConfig', () => {
|
||||
|
@ -103,7 +119,12 @@ describe('loadI18n', () => {
|
|||
});
|
||||
|
||||
it('loads I18n for default config', async () => {
|
||||
await expect(loadI18nTest(DEFAULT_I18N_CONFIG)).resolves.toEqual({
|
||||
await expect(
|
||||
loadI18nTest({
|
||||
i18nConfig: DEFAULT_I18N_CONFIG,
|
||||
currentLocale: 'en',
|
||||
}),
|
||||
).resolves.toEqual({
|
||||
path: 'i18n',
|
||||
defaultLocale: 'en',
|
||||
locales: ['en'],
|
||||
|
@ -120,10 +141,13 @@ describe('loadI18n', () => {
|
|||
it('loads I18n for multi-lang config', async () => {
|
||||
await expect(
|
||||
loadI18nTest({
|
||||
i18nConfig: {
|
||||
path: 'i18n',
|
||||
defaultLocale: 'fr',
|
||||
locales: ['en', 'fr', 'de'],
|
||||
localeConfigs: {},
|
||||
},
|
||||
currentLocale: 'fr',
|
||||
}),
|
||||
).resolves.toEqual({
|
||||
defaultLocale: 'fr',
|
||||
|
@ -133,11 +157,11 @@ describe('loadI18n', () => {
|
|||
localeConfigs: {
|
||||
en: {
|
||||
...getDefaultLocaleConfig('en'),
|
||||
translate: true,
|
||||
translate: false,
|
||||
},
|
||||
fr: {
|
||||
...getDefaultLocaleConfig('fr'),
|
||||
translate: false,
|
||||
translate: true,
|
||||
},
|
||||
de: {
|
||||
...getDefaultLocaleConfig('de'),
|
||||
|
@ -149,15 +173,15 @@ describe('loadI18n', () => {
|
|||
|
||||
it('loads I18n for multi-locale config with specified locale', async () => {
|
||||
await expect(
|
||||
loadI18nTest(
|
||||
{
|
||||
loadI18nTest({
|
||||
i18nConfig: {
|
||||
path: 'i18n',
|
||||
defaultLocale: 'fr',
|
||||
locales: ['en', 'fr', 'de'],
|
||||
localeConfigs: {},
|
||||
},
|
||||
'de',
|
||||
),
|
||||
currentLocale: 'de',
|
||||
}),
|
||||
).resolves.toEqual({
|
||||
defaultLocale: 'fr',
|
||||
path: 'i18n',
|
||||
|
@ -166,11 +190,11 @@ describe('loadI18n', () => {
|
|||
localeConfigs: {
|
||||
en: {
|
||||
...getDefaultLocaleConfig('en'),
|
||||
translate: true,
|
||||
translate: false,
|
||||
},
|
||||
fr: {
|
||||
...getDefaultLocaleConfig('fr'),
|
||||
translate: false,
|
||||
translate: true,
|
||||
},
|
||||
de: {
|
||||
...getDefaultLocaleConfig('de'),
|
||||
|
@ -182,19 +206,19 @@ describe('loadI18n', () => {
|
|||
|
||||
it('loads I18n for multi-locale config with some custom locale configs', async () => {
|
||||
await expect(
|
||||
loadI18nTest(
|
||||
{
|
||||
loadI18nTest({
|
||||
i18nConfig: {
|
||||
path: 'i18n',
|
||||
defaultLocale: 'fr',
|
||||
locales: ['en', 'fr', 'de'],
|
||||
localeConfigs: {
|
||||
fr: {label: 'Français', translate: false},
|
||||
en: {},
|
||||
en: {translate: true},
|
||||
de: {translate: false},
|
||||
},
|
||||
},
|
||||
'de',
|
||||
),
|
||||
currentLocale: 'de',
|
||||
}),
|
||||
).resolves.toEqual({
|
||||
defaultLocale: 'fr',
|
||||
path: 'i18n',
|
||||
|
@ -222,15 +246,15 @@ describe('loadI18n', () => {
|
|||
});
|
||||
|
||||
it('warns when trying to load undeclared locale', async () => {
|
||||
await loadI18nTest(
|
||||
{
|
||||
await loadI18nTest({
|
||||
i18nConfig: {
|
||||
path: 'i18n',
|
||||
defaultLocale: 'fr',
|
||||
locales: ['en', 'fr', 'de'],
|
||||
localeConfigs: {},
|
||||
},
|
||||
'it',
|
||||
);
|
||||
currentLocale: 'it',
|
||||
});
|
||||
expect(consoleSpy.mock.calls[0]![0]).toMatch(
|
||||
/The locale .*it.* was not found in your site configuration/,
|
||||
);
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import logger from '@docusaurus/logger';
|
||||
import combinePromises from 'combine-promises';
|
||||
import type {I18n, DocusaurusConfig, I18nLocaleConfig} from '@docusaurus/types';
|
||||
import type {LoadContextParams} from './site';
|
||||
|
||||
function inferLanguageDisplayName(locale: string) {
|
||||
const tryLocale = (l: string) => {
|
||||
|
@ -98,27 +99,17 @@ export function getDefaultLocaleConfig(
|
|||
}
|
||||
}
|
||||
|
||||
async function shouldTranslateLocale({
|
||||
locale,
|
||||
defaultLocale,
|
||||
localeConfigInput,
|
||||
export async function loadI18n({
|
||||
siteDir,
|
||||
config,
|
||||
currentLocale,
|
||||
}: {
|
||||
locale: string;
|
||||
defaultLocale: string;
|
||||
localeConfigInput: Partial<I18nLocaleConfig>;
|
||||
}): Promise<boolean> {
|
||||
// Maybe in the future we want to check if `./i18n/en` exists?
|
||||
return localeConfigInput.translate ?? locale !== defaultLocale;
|
||||
}
|
||||
|
||||
export async function loadI18n(
|
||||
config: DocusaurusConfig,
|
||||
options?: Pick<LoadContextParams, 'locale'>,
|
||||
): Promise<I18n> {
|
||||
siteDir: string;
|
||||
config: DocusaurusConfig;
|
||||
currentLocale: string;
|
||||
}): Promise<I18n> {
|
||||
const {i18n: i18nConfig} = config;
|
||||
|
||||
const currentLocale = options?.locale ?? i18nConfig.defaultLocale;
|
||||
|
||||
if (!i18nConfig.locales.includes(currentLocale)) {
|
||||
logger.warn`The locale name=${currentLocale} was not found in your site configuration: Available locales are: ${i18nConfig.locales}
|
||||
Note: Docusaurus only support running one locale at a time.`;
|
||||
|
@ -132,14 +123,24 @@ Note: Docusaurus only support running one locale at a time.`;
|
|||
locale: string,
|
||||
): Promise<I18nLocaleConfig> {
|
||||
const localeConfigInput = i18nConfig.localeConfigs[locale] ?? {};
|
||||
const translate = await shouldTranslateLocale({
|
||||
locale,
|
||||
defaultLocale: i18nConfig.defaultLocale,
|
||||
localeConfigInput,
|
||||
});
|
||||
return {
|
||||
const localeConfig: Omit<I18nLocaleConfig, 'translate'> = {
|
||||
...getDefaultLocaleConfig(locale),
|
||||
...localeConfigInput,
|
||||
};
|
||||
|
||||
// By default, translations will be enabled if i18n/<locale> dir exists
|
||||
async function inferTranslate() {
|
||||
const localizationDir = path.resolve(
|
||||
siteDir,
|
||||
i18nConfig.path,
|
||||
localeConfig.path,
|
||||
);
|
||||
return fs.pathExists(localizationDir);
|
||||
}
|
||||
|
||||
const translate = localeConfigInput.translate ?? (await inferTranslate());
|
||||
return {
|
||||
...localeConfig,
|
||||
translate,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -97,7 +97,11 @@ export async function loadContext(
|
|||
siteConfig: initialSiteConfig,
|
||||
});
|
||||
|
||||
const i18n = await loadI18n(initialSiteConfig, {locale});
|
||||
const i18n = await loadI18n({
|
||||
siteDir,
|
||||
config: initialSiteConfig,
|
||||
currentLocale: locale ?? initialSiteConfig.i18n.defaultLocale,
|
||||
});
|
||||
|
||||
const baseUrl = localizePath({
|
||||
path: initialSiteConfig.baseUrl,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue