Add support for locale extensions in pages plugin

This commit is contained in:
sebastienlorber 2024-01-04 18:19:54 +01:00
parent ca09f238f3
commit fc72669528
7 changed files with 90 additions and 14 deletions

View file

@ -11,6 +11,10 @@ module.exports = {
url: 'https://your-docusaurus-site.example.com',
baseUrl: '/',
favicon: 'img/favicon.ico',
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},
markdown: {
parseFrontMatter: async (params) => {
const result = await params.defaultParseFrontMatter(params);

View file

@ -0,0 +1,22 @@
/**
* 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 React from 'react';
import Head from '@docusaurus/Head';
export default class Home extends React.Component {
render() {
return (
<div>
<Head>
<title>translated Hello</title>
</Head>
<div>translated TypeScript...</div>
</div>
);
}
}

View file

@ -69,7 +69,7 @@ exports[`docusaurus-plugin-content-pages loads simple pages with french translat
},
{
"permalink": "/fr/typescript",
"source": "@site/src/pages/typescript.tsx",
"source": "@site/src/pages/typescript.fr.tsx",
"type": "jsx",
},
{

View file

@ -13,7 +13,6 @@ import {
aliasedSitePath,
docuHash,
getPluginI18nPath,
getFolderContainingFile,
addTrailingPathSeparator,
Globby,
createAbsoluteFilePathMatcher,
@ -22,6 +21,7 @@ import {
parseMarkdownFile,
isUnlisted,
isDraft,
findAsyncSequential,
} from '@docusaurus/utils';
import {validatePageFrontMatter} from './frontMatter';
@ -38,6 +38,48 @@ export function getContentPathList(contentPaths: PagesContentPaths): string[] {
return [contentPaths.contentPathLocalized, contentPaths.contentPath];
}
async function getLocalizedSource({
relativeSource,
contentPaths,
locale,
}: {
relativeSource: string;
contentPaths: PagesContentPaths;
locale: string;
}) {
const {name, dir, ext} = path.parse(relativeSource);
// Lookup in localized folder in priority
const possibleSources = getContentPathList(contentPaths).flatMap(
(contentPath) => [
path.join(contentPath, dir, `${name}.${locale}${ext}`),
path.join(contentPath, relativeSource),
],
);
const localizedSource = await findAsyncSequential(
possibleSources,
fs.pathExists,
);
if (!localizedSource) {
throw new Error('unexpected');
}
return localizedSource;
}
function filterLocaleExtensionFiles(
files: string[],
locales: string[],
): string[] {
const localeExtensions = locales.map((locale) => `.${locale}`);
return files.filter((file) => {
const {name} = path.parse(file);
return !localeExtensions.includes(path.extname(name));
});
}
const isMarkdownSource = (source: string) =>
source.endsWith('.md') || source.endsWith('.mdx');
@ -62,6 +104,14 @@ export default function pluginContentPages(
);
const dataDir = path.join(pluginDataDirRoot, options.id ?? DEFAULT_PLUGIN_ID);
async function getPageFiles() {
const files = await Globby(options.include, {
cwd: contentPaths.contentPath,
ignore: options.exclude,
});
return filterLocaleExtensionFiles(files, context.i18n.locales);
}
return {
name: 'docusaurus-plugin-content-pages',
@ -73,28 +123,21 @@ export default function pluginContentPages(
},
async loadContent() {
const {include} = options;
if (!(await fs.pathExists(contentPaths.contentPath))) {
return null;
}
const {baseUrl} = siteConfig;
const pagesFiles = await Globby(include, {
cwd: contentPaths.contentPath,
ignore: options.exclude,
});
const pagesFiles = await getPageFiles();
async function processPageSourceFile(
relativeSource: string,
): Promise<Metadata | undefined> {
// Lookup in localized folder in priority
const contentPath = await getFolderContainingFile(
getContentPathList(contentPaths),
const source = await getLocalizedSource({
relativeSource,
);
const source = path.join(contentPath, relativeSource);
contentPaths,
locale: context.i18n.currentLocale,
});
const aliasedSourcePath = aliasedSitePath(source, siteDir);
const permalink = normalizeUrl([
baseUrl,

View file

@ -0,0 +1,3 @@
# Page i18n test
French version

View file

@ -0,0 +1,3 @@
# Page i18n test
English version

View file

@ -26,6 +26,7 @@ import Readme from "../README.mdx"
### Other tests
- [React 18](/tests/pages/react-18)
- [i18n](/tests/pages/i18n)
- [Crash test](/tests/pages/crashTest)
- [Code block tests](/tests/pages/code-block-tests)
- [Link tests](/tests/pages/link-tests)