mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-28 17:57:48 +02:00
refactor, create getLocalizedSource()
This commit is contained in:
parent
ecf6888840
commit
e9b20ca990
5 changed files with 107 additions and 51 deletions
|
@ -26,6 +26,8 @@ import {
|
|||
getContentPathList,
|
||||
isUnlisted,
|
||||
isDraft,
|
||||
filterFilesWithLocaleExtension,
|
||||
getLocalizedSource,
|
||||
} from '@docusaurus/utils';
|
||||
import {validateBlogPostFrontMatter} from './frontMatter';
|
||||
import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors';
|
||||
|
@ -208,13 +210,19 @@ async function parseBlogPostMarkdownFile({
|
|||
const defaultReadingTime: ReadingTimeFunction = ({content, options}) =>
|
||||
readingTime(content, options).minutes;
|
||||
|
||||
async function processBlogSourceFile(
|
||||
blogSourceRelative: string,
|
||||
contentPaths: BlogContentPaths,
|
||||
context: LoadContext,
|
||||
options: PluginOptions,
|
||||
authorsMap?: AuthorsMap,
|
||||
): Promise<BlogPost | undefined> {
|
||||
async function processBlogSourceFile({
|
||||
blogSourceRelative,
|
||||
contentPaths,
|
||||
context,
|
||||
options,
|
||||
authorsMap,
|
||||
}: {
|
||||
blogSourceRelative: string;
|
||||
contentPaths: BlogContentPaths;
|
||||
context: LoadContext;
|
||||
options: PluginOptions;
|
||||
authorsMap?: AuthorsMap;
|
||||
}): Promise<BlogPost | undefined> {
|
||||
const {
|
||||
siteConfig: {
|
||||
baseUrl,
|
||||
|
@ -231,21 +239,30 @@ async function processBlogSourceFile(
|
|||
editUrl,
|
||||
} = options;
|
||||
|
||||
// TODO remove this in favor of getLocalizedSource
|
||||
// Lookup in localized folder in priority
|
||||
const blogDirPath = await getFolderContainingFile(
|
||||
getContentPathList(contentPaths),
|
||||
blogSourceRelative,
|
||||
);
|
||||
|
||||
const blogSourceAbsolute = path.join(blogDirPath, blogSourceRelative);
|
||||
const {
|
||||
source: blogSource,
|
||||
|
||||
// contentPath: blogDirPath
|
||||
} = await getLocalizedSource({
|
||||
relativeSource: blogSourceRelative,
|
||||
contentPaths,
|
||||
locale: context.i18n.currentLocale,
|
||||
});
|
||||
|
||||
const {frontMatter, content, contentTitle, excerpt} =
|
||||
await parseBlogPostMarkdownFile({
|
||||
filePath: blogSourceAbsolute,
|
||||
filePath: blogSource,
|
||||
parseFrontMatter,
|
||||
});
|
||||
|
||||
const aliasedSource = aliasedSitePath(blogSourceAbsolute, siteDir);
|
||||
const aliasedSource = aliasedSitePath(blogSource, siteDir);
|
||||
|
||||
const draft = isDraft({frontMatter});
|
||||
const unlisted = isUnlisted({frontMatter});
|
||||
|
@ -274,14 +291,14 @@ async function processBlogSourceFile(
|
|||
}
|
||||
|
||||
try {
|
||||
const result = getFileCommitDate(blogSourceAbsolute, {
|
||||
const result = getFileCommitDate(blogSource, {
|
||||
age: 'oldest',
|
||||
includeAuthor: false,
|
||||
});
|
||||
return result.date;
|
||||
} catch (err) {
|
||||
logger.warn(err);
|
||||
return (await fs.stat(blogSourceAbsolute)).birthtime;
|
||||
return (await fs.stat(blogSource)).birthtime;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -302,7 +319,7 @@ async function processBlogSourceFile(
|
|||
function getBlogEditUrl() {
|
||||
const blogPathRelative = path.relative(
|
||||
blogDirPath,
|
||||
path.resolve(blogSourceAbsolute),
|
||||
path.resolve(blogSource),
|
||||
);
|
||||
|
||||
if (typeof editUrl === 'function') {
|
||||
|
@ -374,28 +391,36 @@ export async function generateBlogPosts(
|
|||
return [];
|
||||
}
|
||||
|
||||
const blogSourceFiles = await Globby(include, {
|
||||
cwd: contentPaths.contentPath,
|
||||
ignore: exclude,
|
||||
});
|
||||
async function getBlogSourceFiles() {
|
||||
const files = await Globby(include, {
|
||||
cwd: contentPaths.contentPath,
|
||||
ignore: exclude,
|
||||
});
|
||||
return filterFilesWithLocaleExtension({
|
||||
files,
|
||||
locales: context.i18n.locales,
|
||||
});
|
||||
}
|
||||
|
||||
const blogSourceFiles = await getBlogSourceFiles();
|
||||
|
||||
const authorsMap = await getAuthorsMap({
|
||||
contentPaths,
|
||||
authorsMapPath: options.authorsMapPath,
|
||||
});
|
||||
|
||||
async function doProcessBlogSourceFile(blogSourceFile: string) {
|
||||
async function doProcessBlogSourceFile(blogSourceRelative: string) {
|
||||
try {
|
||||
return await processBlogSourceFile(
|
||||
blogSourceFile,
|
||||
return await processBlogSourceFile({
|
||||
blogSourceRelative,
|
||||
contentPaths,
|
||||
context,
|
||||
options,
|
||||
authorsMap,
|
||||
);
|
||||
});
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Processing of blog source file path=${blogSourceFile} failed.`,
|
||||
`Processing of blog source file path=${blogSourceRelative} failed.`,
|
||||
{cause: err as Error},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
|||
* preserved as-is. Default values will be applied when generating metadata
|
||||
*/
|
||||
export type BlogPostFrontMatter = {
|
||||
// TODO Docusaurus v4: remove
|
||||
/**
|
||||
* @deprecated Use `slug` instead.
|
||||
*/
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
parseMarkdownFile,
|
||||
isUnlisted,
|
||||
isDraft,
|
||||
getLocalizedSourcePath,
|
||||
getLocalizedSource,
|
||||
filterFilesWithLocaleExtension,
|
||||
} from '@docusaurus/utils';
|
||||
import {validatePageFrontMatter} from './frontMatter';
|
||||
|
@ -95,7 +95,7 @@ export default function pluginContentPages(
|
|||
async function processPageSourceFile(
|
||||
relativeSource: string,
|
||||
): Promise<Metadata | undefined> {
|
||||
const source = await getLocalizedSourcePath({
|
||||
const {source} = await getLocalizedSource({
|
||||
relativeSource,
|
||||
contentPaths,
|
||||
locale: context.i18n.currentLocale,
|
||||
|
|
|
@ -127,13 +127,13 @@ function addLocaleExtension(filePath: string, locale: string) {
|
|||
return path.join(dir, `${name}.${locale}${ext}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first existing localized path of a content file
|
||||
* @param relativeSource
|
||||
* @param contentPaths
|
||||
* @param locale
|
||||
*/
|
||||
export async function getLocalizedSourcePath({
|
||||
type LocalizedSource = {
|
||||
contentPath: string;
|
||||
source: string;
|
||||
type: 'locale-extension' | 'locale-folder' | 'original';
|
||||
};
|
||||
|
||||
function getLocalizedSourceCandidates({
|
||||
relativeSource,
|
||||
contentPaths,
|
||||
locale,
|
||||
|
@ -141,38 +141,68 @@ export async function getLocalizedSourcePath({
|
|||
relativeSource: string;
|
||||
contentPaths: ContentPaths;
|
||||
locale: string;
|
||||
}): Promise<string> {
|
||||
}): LocalizedSource[] {
|
||||
// docs/myDoc.fr.md
|
||||
const localeExtensionSource = path.join(
|
||||
contentPaths.contentPath,
|
||||
addLocaleExtension(relativeSource, locale),
|
||||
);
|
||||
const localeExtensionSource: LocalizedSource = {
|
||||
contentPath: contentPaths.contentPath,
|
||||
source: path.join(
|
||||
contentPaths.contentPath,
|
||||
addLocaleExtension(relativeSource, locale),
|
||||
),
|
||||
type: 'locale-extension',
|
||||
};
|
||||
|
||||
// i18n/fr/docs/current/myDoc.md
|
||||
const i18nFolderSource = path.join(
|
||||
contentPaths.contentPathLocalized,
|
||||
relativeSource,
|
||||
);
|
||||
const i18nFolderSource: LocalizedSource = {
|
||||
contentPath: contentPaths.contentPath,
|
||||
source: path.join(contentPaths.contentPathLocalized, relativeSource),
|
||||
type: 'locale-folder',
|
||||
};
|
||||
|
||||
// docs/myDoc.md
|
||||
const originalSource = path.join(contentPaths.contentPath, relativeSource);
|
||||
const originalSource: LocalizedSource = {
|
||||
contentPath: contentPaths.contentPath,
|
||||
source: path.join(contentPaths.contentPath, relativeSource),
|
||||
type: 'original',
|
||||
};
|
||||
|
||||
// Order matters
|
||||
const possibleSources = [
|
||||
localeExtensionSource,
|
||||
i18nFolderSource,
|
||||
originalSource,
|
||||
];
|
||||
return [localeExtensionSource, i18nFolderSource, originalSource];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first existing localized path of a content file
|
||||
* @param relativeSource
|
||||
* @param contentPaths
|
||||
* @param locale
|
||||
*/
|
||||
export async function getLocalizedSource({
|
||||
relativeSource,
|
||||
contentPaths,
|
||||
locale,
|
||||
}: {
|
||||
relativeSource: string;
|
||||
contentPaths: ContentPaths;
|
||||
locale: string;
|
||||
}): Promise<LocalizedSource> {
|
||||
// docs/myDoc.fr.md
|
||||
const candidates = getLocalizedSourceCandidates({
|
||||
relativeSource,
|
||||
contentPaths,
|
||||
locale,
|
||||
});
|
||||
|
||||
// TODO can we avoid/optimize this by passing all the files we know as param?
|
||||
const localizedSource = await findAsyncSequential(
|
||||
possibleSources,
|
||||
fs.pathExists,
|
||||
const localizedSource = await findAsyncSequential(candidates, (candidate) =>
|
||||
fs.pathExists(candidate.source),
|
||||
);
|
||||
|
||||
if (!localizedSource) {
|
||||
throw new Error(
|
||||
`Unexpected error, couldn't find any existing file at ${originalSource}`,
|
||||
`Unexpected error, couldn't find any localized source for file at ${path.join(
|
||||
contentPaths.contentPath,
|
||||
relativeSource,
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ export {
|
|||
updateTranslationFileMessages,
|
||||
getPluginI18nPath,
|
||||
localizePath,
|
||||
getLocalizedSourcePath,
|
||||
getLocalizedSource,
|
||||
filterFilesWithLocaleExtension,
|
||||
} from './i18nUtils';
|
||||
export {
|
||||
|
|
Loading…
Add table
Reference in a new issue