diff --git a/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/docusaurus.config.js b/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/docusaurus.config.js index d048d2caf5..b6b686f517 100644 --- a/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/docusaurus.config.js +++ b/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/docusaurus.config.js @@ -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); diff --git a/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/src/pages/typescript.fr.tsx b/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/src/pages/typescript.fr.tsx new file mode 100644 index 0000000000..96e86b6afd --- /dev/null +++ b/packages/docusaurus-plugin-content-pages/src/__tests__/__fixtures__/website/src/pages/typescript.fr.tsx @@ -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 ( +
+ + translated Hello + +
translated TypeScript...
+
+ ); + } +} diff --git a/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap index fc5fa21967..f082b1028e 100644 --- a/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-pages/src/__tests__/__snapshots__/index.test.ts.snap @@ -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", }, { diff --git a/packages/docusaurus-plugin-content-pages/src/index.ts b/packages/docusaurus-plugin-content-pages/src/index.ts index a4707110f2..01b0d0d5cf 100644 --- a/packages/docusaurus-plugin-content-pages/src/index.ts +++ b/packages/docusaurus-plugin-content-pages/src/index.ts @@ -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 { - // 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, diff --git a/website/_dogfooding/_pages tests/i18n/index.fr.md b/website/_dogfooding/_pages tests/i18n/index.fr.md new file mode 100644 index 0000000000..4917f6b55f --- /dev/null +++ b/website/_dogfooding/_pages tests/i18n/index.fr.md @@ -0,0 +1,3 @@ +# Page i18n test + +French version diff --git a/website/_dogfooding/_pages tests/i18n/index.md b/website/_dogfooding/_pages tests/i18n/index.md new file mode 100644 index 0000000000..3d23cbe7b9 --- /dev/null +++ b/website/_dogfooding/_pages tests/i18n/index.md @@ -0,0 +1,3 @@ +# Page i18n test + +English version diff --git a/website/_dogfooding/_pages tests/index.mdx b/website/_dogfooding/_pages tests/index.mdx index 4f7c2889bf..851eebb038 100644 --- a/website/_dogfooding/_pages tests/index.mdx +++ b/website/_dogfooding/_pages tests/index.mdx @@ -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)