mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-11 08:07:26 +02:00
feat(v2): editUrl function for advanced use-cases (#4121)
* EditUrl function * normalize blog/docs regarding the editUrl feature + editUrl function * editUrl fn => always inject posix style relative paths, make tests more reliable (see also https://github.com/facebook/docusaurus/issues/4124) * fix editUrl on windows
This commit is contained in:
parent
15c50e2ecb
commit
be7b5dca78
15 changed files with 368 additions and 69 deletions
|
@ -15,6 +15,7 @@ import {
|
|||
MetadataOptions,
|
||||
VersionMetadata,
|
||||
PluginOptions,
|
||||
EditUrlFunction,
|
||||
} from '../types';
|
||||
import {LoadContext} from '@docusaurus/types';
|
||||
import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
|
||||
|
@ -285,6 +286,45 @@ describe('simple site', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('docs with function editUrl', async () => {
|
||||
const hardcodedEditUrl = 'hardcoded-edit-url';
|
||||
|
||||
const editUrlFunction: EditUrlFunction = jest.fn(() => hardcodedEditUrl);
|
||||
|
||||
const {siteDir, context, options, currentVersion} = await loadSite({
|
||||
options: {
|
||||
editUrl: editUrlFunction,
|
||||
},
|
||||
});
|
||||
|
||||
const testUtilsLocal = createTestUtils({
|
||||
siteDir,
|
||||
context,
|
||||
options,
|
||||
versionMetadata: currentVersion,
|
||||
});
|
||||
|
||||
await testUtilsLocal.testMeta(path.join('foo', 'baz.md'), {
|
||||
version: 'current',
|
||||
id: 'foo/baz',
|
||||
unversionedId: 'foo/baz',
|
||||
isDocsHomePage: false,
|
||||
permalink: '/docs/foo/bazSlug.html',
|
||||
slug: '/foo/bazSlug.html',
|
||||
title: 'baz',
|
||||
editUrl: hardcodedEditUrl,
|
||||
description: 'Images',
|
||||
});
|
||||
|
||||
expect(editUrlFunction).toHaveBeenCalledTimes(1);
|
||||
expect(editUrlFunction).toHaveBeenCalledWith({
|
||||
version: 'current',
|
||||
versionDocsDirPath: 'docs',
|
||||
docPath: path.posix.join('foo', 'baz.md'),
|
||||
locale: 'en',
|
||||
});
|
||||
});
|
||||
|
||||
test('docs with last update time and author', async () => {
|
||||
const {siteDir, context, options, currentVersion} = await loadSite({
|
||||
options: {
|
||||
|
@ -595,6 +635,47 @@ describe('versioned site', () => {
|
|||
);
|
||||
});
|
||||
|
||||
test('doc with editUrl function', async () => {
|
||||
const hardcodedEditUrl = 'hardcoded-edit-url';
|
||||
|
||||
const editUrlFunction: EditUrlFunction = jest.fn(() => hardcodedEditUrl);
|
||||
|
||||
const {siteDir, context, options, version100} = await loadSite({
|
||||
options: {
|
||||
editUrl: editUrlFunction,
|
||||
},
|
||||
});
|
||||
|
||||
const testUtilsLocal = createTestUtils({
|
||||
siteDir,
|
||||
context,
|
||||
options,
|
||||
versionMetadata: version100,
|
||||
});
|
||||
|
||||
await testUtilsLocal.testMeta(path.join('hello.md'), {
|
||||
id: 'version-1.0.0/hello',
|
||||
unversionedId: 'hello',
|
||||
isDocsHomePage: false,
|
||||
permalink: '/docs/1.0.0/hello',
|
||||
slug: '/hello',
|
||||
title: 'hello',
|
||||
description: 'Hello 1.0.0 ! (translated en)',
|
||||
version: '1.0.0',
|
||||
source:
|
||||
'@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md',
|
||||
editUrl: hardcodedEditUrl,
|
||||
});
|
||||
|
||||
expect(editUrlFunction).toHaveBeenCalledTimes(1);
|
||||
expect(editUrlFunction).toHaveBeenCalledWith({
|
||||
version: '1.0.0',
|
||||
versionDocsDirPath: 'versioned_docs/version-1.0.0',
|
||||
docPath: path.join('hello.md'),
|
||||
locale: 'en',
|
||||
});
|
||||
});
|
||||
|
||||
test('translated doc with editUrl', async () => {
|
||||
const {siteDir, context, options, version100} = await loadSite({
|
||||
options: {
|
||||
|
@ -657,11 +738,11 @@ describe('versioned site', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('translated fr doc with editUrl and editLocalizedDocs=true', async () => {
|
||||
test('translated fr doc with editUrl and editLocalizedFiles=true', async () => {
|
||||
const {siteDir, context, options, version100} = await loadSite({
|
||||
options: {
|
||||
editUrl: 'https://github.com/facebook/docusaurus/edit/master/website',
|
||||
editLocalizedDocs: true,
|
||||
editLocalizedFiles: true,
|
||||
},
|
||||
locale: 'fr',
|
||||
});
|
||||
|
@ -689,12 +770,12 @@ describe('versioned site', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('translated fr doc with editUrl and editLocalizedDocs=true + editCurrentVersion=true', async () => {
|
||||
test('translated fr doc with editUrl and editLocalizedFiles=true + editCurrentVersion=true', async () => {
|
||||
const {siteDir, context, options, version100} = await loadSite({
|
||||
options: {
|
||||
editUrl: 'https://github.com/facebook/docusaurus/edit/master/website',
|
||||
editCurrentVersion: true,
|
||||
editLocalizedDocs: true,
|
||||
editLocalizedFiles: true,
|
||||
},
|
||||
locale: 'fr',
|
||||
});
|
||||
|
|
|
@ -39,7 +39,7 @@ describe('normalizeDocsPluginOptions', () => {
|
|||
includeCurrentVersion: false,
|
||||
disableVersioning: true,
|
||||
editCurrentVersion: true,
|
||||
editLocalizedDocs: true,
|
||||
editLocalizedFiles: true,
|
||||
versions: {
|
||||
current: {
|
||||
path: 'next',
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
getFolderContainingFile,
|
||||
normalizeUrl,
|
||||
parseMarkdownString,
|
||||
posixPath,
|
||||
} from '@docusaurus/utils';
|
||||
import {LoadContext} from '@docusaurus/types';
|
||||
|
||||
|
@ -120,14 +121,29 @@ export function processDocMetadata({
|
|||
|
||||
const relativeFilePath = path.relative(docsDirPath, filePath);
|
||||
|
||||
const isLocalized = docsDirPath === versionMetadata.docsDirPathLocalized;
|
||||
function getDocEditUrl() {
|
||||
if (typeof options.editUrl === 'function') {
|
||||
return options.editUrl({
|
||||
version: versionMetadata.versionName,
|
||||
versionDocsDirPath: posixPath(
|
||||
path.relative(siteDir, versionMetadata.docsDirPath),
|
||||
),
|
||||
docPath: posixPath(relativeFilePath),
|
||||
locale: context.i18n.currentLocale,
|
||||
});
|
||||
} else if (typeof options.editUrl === 'string') {
|
||||
const isLocalized = docsDirPath === versionMetadata.docsDirPathLocalized;
|
||||
const baseVersionEditUrl =
|
||||
isLocalized && options.editLocalizedFiles
|
||||
? versionMetadata.versionEditUrlLocalized
|
||||
: versionMetadata.versionEditUrl;
|
||||
return getEditUrl(relativeFilePath, baseVersionEditUrl);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const versionEditUrl =
|
||||
isLocalized && options.editLocalizedDocs
|
||||
? versionMetadata.versionEditUrlLocalized
|
||||
: versionMetadata.versionEditUrl;
|
||||
|
||||
const docsEditUrl = getEditUrl(relativeFilePath, versionEditUrl);
|
||||
const docsEditUrl = getDocEditUrl();
|
||||
|
||||
const {frontMatter = {}, excerpt} = parseMarkdownString(content);
|
||||
const {sidebar_label, custom_edit_url} = frontMatter;
|
||||
|
|
|
@ -38,7 +38,7 @@ export const DEFAULT_OPTIONS: Omit<PluginOptions, 'id'> = {
|
|||
lastVersion: undefined,
|
||||
versions: {},
|
||||
editCurrentVersion: false,
|
||||
editLocalizedDocs: false,
|
||||
editLocalizedFiles: false,
|
||||
};
|
||||
|
||||
const VersionOptionsSchema = Joi.object({
|
||||
|
@ -52,9 +52,9 @@ const VersionsOptionsSchema = Joi.object()
|
|||
|
||||
export const OptionsSchema = Joi.object({
|
||||
path: Joi.string().default(DEFAULT_OPTIONS.path),
|
||||
editUrl: URISchema,
|
||||
editUrl: Joi.alternatives().try(URISchema, Joi.function()),
|
||||
editCurrentVersion: Joi.boolean().default(DEFAULT_OPTIONS.editCurrentVersion),
|
||||
editLocalizedDocs: Joi.boolean().default(DEFAULT_OPTIONS.editLocalizedDocs),
|
||||
editLocalizedFiles: Joi.boolean().default(DEFAULT_OPTIONS.editLocalizedFiles),
|
||||
routeBasePath: Joi.string()
|
||||
// '' not allowed, see https://github.com/facebook/docusaurus/issues/3374
|
||||
// .allow('') ""
|
||||
|
|
|
@ -31,12 +31,19 @@ export type VersionMetadata = {
|
|||
routePriority: number | undefined; // -1 for the latest docs
|
||||
};
|
||||
|
||||
export type EditUrlFunction = (editUrlParams: {
|
||||
version: string;
|
||||
versionDocsDirPath: string;
|
||||
docPath: string;
|
||||
locale: string;
|
||||
}) => string | undefined;
|
||||
|
||||
export type MetadataOptions = {
|
||||
routeBasePath: string;
|
||||
homePageId?: string;
|
||||
editUrl?: string;
|
||||
editUrl?: string | EditUrlFunction;
|
||||
editCurrentVersion: boolean;
|
||||
editLocalizedDocs: boolean;
|
||||
editLocalizedFiles: boolean;
|
||||
showLastUpdateTime?: boolean;
|
||||
showLastUpdateAuthor?: boolean;
|
||||
};
|
||||
|
|
|
@ -211,6 +211,12 @@ function getVersionEditUrls({
|
|||
return undefined;
|
||||
}
|
||||
|
||||
// if the user is using the functional form of editUrl,
|
||||
// he has total freedom and we can't compute a "version edit url"
|
||||
if (typeof editUrl === 'function') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const editDirPath = editCurrentVersion ? currentVersionPath : docsDirPath;
|
||||
const editDirPathLocalized = editCurrentVersion
|
||||
? getDocsDirPathLocalized({
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue