mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-10 15:47:23 +02:00
feat(v2): createData plugin API (#1400)
* feat(v2): createModule plugin api * remove unused stuff * address review, createModule -> createData * link.link -> link.url * remove youtube page * update yarn.lock
This commit is contained in:
parent
195e934858
commit
b3cf9c62d5
18 changed files with 164 additions and 349 deletions
|
@ -8,7 +8,7 @@
|
|||
const globby = require('globby');
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const {parse, idx, normalizeUrl} = require('@docusaurus/utils');
|
||||
const {parse, idx, normalizeUrl, docuHash} = require('@docusaurus/utils');
|
||||
|
||||
// TODO: Use a better slugify function that doesn't rely on a specific file extension.
|
||||
function fileToUrl(fileName) {
|
||||
|
@ -20,8 +20,6 @@ function fileToUrl(fileName) {
|
|||
}
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
metadataKey: 'blogMetadata',
|
||||
metadataFileName: 'blogMetadata.json',
|
||||
path: 'blog', // Path to data on filesystem, relative to site dir.
|
||||
routeBasePath: 'blog', // URL Route.
|
||||
include: ['*.md', '*.mdx'], // Extensions to include.
|
||||
|
@ -121,40 +119,46 @@ class DocusaurusPluginContentBlog {
|
|||
|
||||
async contentLoaded({content, actions}) {
|
||||
const {blogPageComponent, blogPostComponent} = this.options;
|
||||
const {addRoute} = actions;
|
||||
content.forEach(metadataItem => {
|
||||
const {isBlogPage, permalink} = metadataItem;
|
||||
if (isBlogPage) {
|
||||
const {addRoute, createData} = actions;
|
||||
await Promise.all(
|
||||
content.map(async metadataItem => {
|
||||
const {isBlogPage, permalink} = metadataItem;
|
||||
const metadataPath = await createData(
|
||||
`${docuHash(permalink)}.json`,
|
||||
JSON.stringify(metadataItem, null, 2),
|
||||
);
|
||||
if (isBlogPage) {
|
||||
addRoute({
|
||||
path: permalink,
|
||||
component: blogPageComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
entries: metadataItem.posts.map(post => ({
|
||||
// To tell routes.js this is an import and not a nested object to recurse.
|
||||
__import: true,
|
||||
path: post.source,
|
||||
query: {
|
||||
truncated: true,
|
||||
},
|
||||
})),
|
||||
metadata: metadataPath,
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
addRoute({
|
||||
path: permalink,
|
||||
component: blogPageComponent,
|
||||
component: blogPostComponent,
|
||||
exact: true,
|
||||
metadata: metadataItem,
|
||||
modules: {
|
||||
entries: metadataItem.posts.map(post => ({
|
||||
// To tell routes.js this is an import and not a nested object to recurse.
|
||||
__import: true,
|
||||
path: post.source,
|
||||
query: {
|
||||
truncated: true,
|
||||
},
|
||||
})),
|
||||
content: metadataItem.source,
|
||||
metadata: metadataPath,
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
addRoute({
|
||||
path: permalink,
|
||||
component: blogPostComponent,
|
||||
exact: true,
|
||||
metadata: metadataItem,
|
||||
modules: {
|
||||
content: metadataItem.source,
|
||||
},
|
||||
});
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
configureWebpack(config, isServer, {getBabelLoader, getCacheLoader}) {
|
||||
|
|
|
@ -8,15 +8,18 @@
|
|||
const globby = require('globby');
|
||||
const importFresh = require('import-fresh');
|
||||
const path = require('path');
|
||||
const {getSubFolder, idx, normalizeUrl} = require('@docusaurus/utils');
|
||||
const {
|
||||
getSubFolder,
|
||||
idx,
|
||||
normalizeUrl,
|
||||
docuHash,
|
||||
} = require('@docusaurus/utils');
|
||||
|
||||
const createOrder = require('./order');
|
||||
const loadSidebars = require('./sidebars');
|
||||
const processMetadata = require('./metadata');
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
metadataKey: 'docsMetadata',
|
||||
metadataFileName: 'docsMetadata.json',
|
||||
path: 'docs', // Path to data on filesystem, relative to site dir.
|
||||
routeBasePath: 'docs', // URL Route.
|
||||
include: ['**/*.md', '**/*.mdx'], // Extensions to include.
|
||||
|
@ -182,21 +185,26 @@ class DocusaurusPluginContentDocs {
|
|||
}
|
||||
});
|
||||
|
||||
// Create source to metadata mapping.
|
||||
const sourceToMetadata = {};
|
||||
Object.values(docs).forEach(({source, version, permalink, language}) => {
|
||||
sourceToMetadata[source] = {
|
||||
version,
|
||||
permalink,
|
||||
language,
|
||||
};
|
||||
});
|
||||
const permalinkToId = {};
|
||||
Object.values(docs).forEach(
|
||||
({id, source, version, permalink, language}) => {
|
||||
sourceToMetadata[source] = {
|
||||
version,
|
||||
permalink,
|
||||
language,
|
||||
};
|
||||
|
||||
permalinkToId[permalink] = id;
|
||||
},
|
||||
);
|
||||
|
||||
this.content = {
|
||||
docs,
|
||||
docsDir,
|
||||
docsSidebars,
|
||||
sourceToMetadata,
|
||||
permalinkToId,
|
||||
translatedDir,
|
||||
versionedDir,
|
||||
};
|
||||
|
@ -206,20 +214,38 @@ class DocusaurusPluginContentDocs {
|
|||
|
||||
async contentLoaded({content, actions}) {
|
||||
const {docLayoutComponent, docItemComponent, routeBasePath} = this.options;
|
||||
const {addRoute} = actions;
|
||||
const {addRoute, createData} = actions;
|
||||
|
||||
const routes = await Promise.all(
|
||||
Object.values(content.docs).map(async metadataItem => {
|
||||
const metadataPath = await createData(
|
||||
`${docuHash(metadataItem.permalink)}.json`,
|
||||
JSON.stringify(metadataItem, null, 2),
|
||||
);
|
||||
return {
|
||||
path: metadataItem.permalink,
|
||||
component: docItemComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
content: metadataItem.source,
|
||||
metadata: metadataPath,
|
||||
},
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
const docsMetadataPath = await createData(
|
||||
`docsMetadata.json`,
|
||||
JSON.stringify(content, null, 2),
|
||||
);
|
||||
|
||||
addRoute({
|
||||
path: normalizeUrl([this.context.siteConfig.baseUrl, routeBasePath]),
|
||||
component: docLayoutComponent,
|
||||
routes: Object.values(content.docs).map(metadataItem => ({
|
||||
path: metadataItem.permalink,
|
||||
component: docItemComponent,
|
||||
exact: true,
|
||||
metadata: metadataItem,
|
||||
modules: {
|
||||
content: metadataItem.source,
|
||||
},
|
||||
})),
|
||||
routes,
|
||||
modules: {
|
||||
docsMetadata: docsMetadataPath,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,9 @@
|
|||
|
||||
const globby = require('globby');
|
||||
const path = require('path');
|
||||
const {encodePath, fileToPath, idx} = require('@docusaurus/utils');
|
||||
const {encodePath, fileToPath, idx, docuHash} = require('@docusaurus/utils');
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
metadataKey: 'pagesMetadata',
|
||||
metadataFileName: 'pagesMetadata.json',
|
||||
path: 'pages', // Path to data on filesystem, relative to site dir.
|
||||
routeBasePath: '', // URL Route.
|
||||
include: ['**/*.{js,jsx}'], // Extensions to include.
|
||||
|
@ -96,20 +94,26 @@ class DocusaurusPluginContentPages {
|
|||
|
||||
async contentLoaded({content, actions}) {
|
||||
const {component} = this.options;
|
||||
const {addRoute} = actions;
|
||||
const {addRoute, createData} = actions;
|
||||
|
||||
content.forEach(metadataItem => {
|
||||
const {permalink, source} = metadataItem;
|
||||
addRoute({
|
||||
path: permalink,
|
||||
component,
|
||||
exact: true,
|
||||
metadata: metadataItem,
|
||||
modules: {
|
||||
content: source,
|
||||
},
|
||||
});
|
||||
});
|
||||
await Promise.all(
|
||||
content.map(async metadataItem => {
|
||||
const {permalink, source} = metadataItem;
|
||||
const metadataPath = await createData(
|
||||
`${docuHash(permalink)}.json`,
|
||||
JSON.stringify(metadataItem, null, 2),
|
||||
);
|
||||
addRoute({
|
||||
path: permalink,
|
||||
component,
|
||||
exact: true,
|
||||
modules: {
|
||||
content: source,
|
||||
metadata: metadataPath,
|
||||
},
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,3 +7,17 @@
|
|||
- `docsUrl`. Use the plugin option on `docusaurus-plugin-content-docs` instead.
|
||||
- `customDocsPath`. Use the plugin option on `docusaurus-plugin-content-docs` instead.
|
||||
- `sidebars.json` now has to be explicitly loaded by users and passed into the the plugin option on `docusaurus-plugin-content-docs`.
|
||||
- `headerLinks` doc, page, blog is deprecated. The syntax is now:
|
||||
|
||||
```js
|
||||
headerLinks: [
|
||||
// Link to internal page (without baseUrl)
|
||||
{ url: "help", label: "Help" },
|
||||
// Links to href destination/ external page
|
||||
{ href: "https://github.com/", label: "GitHub" },
|
||||
// Determines search bar position among links
|
||||
{ search: true },
|
||||
// Determines language drop down position among links
|
||||
{ languages: true }
|
||||
],
|
||||
```js
|
||||
|
|
|
@ -10,7 +10,7 @@ import {renderRoutes} from 'react-router-config';
|
|||
|
||||
import Head from '@docusaurus/Head'; // eslint-disable-line
|
||||
import routes from '@generated/routes'; // eslint-disable-line
|
||||
import metadata from '@generated/metadata'; // eslint-disable-line
|
||||
import env from '@generated/env'; // eslint-disable-line
|
||||
import siteConfig from '@generated/docusaurus.config'; //eslint-disable-line
|
||||
import DocusaurusContext from '@docusaurus/context'; // eslint-disable-line
|
||||
import PendingNavigation from './PendingNavigation';
|
||||
|
@ -19,7 +19,7 @@ function App() {
|
|||
const [context, setContext] = useState({});
|
||||
return (
|
||||
<DocusaurusContext.Provider
|
||||
value={{siteConfig, ...metadata, ...context, setContext}}>
|
||||
value={{siteConfig, env, ...context, setContext}}>
|
||||
{/* TODO: this link stylesheet to infima is temporary */}
|
||||
<Head>
|
||||
<link
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
<% imports.forEach(({name, path}) => { %>
|
||||
import <%= name %> from '<%= path %>';
|
||||
<% }); %>
|
||||
|
||||
const contents = {
|
||||
<% imports.forEach(({name}) => { %>
|
||||
<%= name %>,
|
||||
<% }); %>
|
||||
};
|
||||
|
||||
export default contents;
|
|
@ -20,7 +20,7 @@ import styles from './styles.module.css';
|
|||
|
||||
function Doc(props) {
|
||||
const {siteConfig = {}} = useContext(DocusaurusContext);
|
||||
const {route} = props;
|
||||
const {route, docsMetadata, location} = props;
|
||||
const {baseUrl, favicon} = siteConfig;
|
||||
return (
|
||||
<Layout>
|
||||
|
@ -28,9 +28,11 @@ function Doc(props) {
|
|||
<title>{siteConfig.title}</title>
|
||||
{favicon && <link rel="shortcut icon" href={baseUrl + favicon} />}
|
||||
</Head>
|
||||
<Sidebar />
|
||||
<Sidebar docsMetadata={docsMetadata} location={location} />
|
||||
<div className={styles.mainContainer}>
|
||||
<div className={styles.docContainer}>{renderRoutes(route.routes)}</div>
|
||||
<div className={styles.docContainer}>
|
||||
{renderRoutes(route.routes, {docsMetadata})}
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
|
|
|
@ -5,10 +5,9 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React, {useContext, useEffect} from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import DocsPaginator from '@theme/DocsPaginator'; // eslint-disable-line
|
||||
import DocusaurusContext from '@docusaurus/context';
|
||||
import Head from '@docusaurus/Head';
|
||||
|
||||
import './styles.css';
|
||||
|
@ -31,12 +30,8 @@ const Headings = ({headings, isChild}) => {
|
|||
};
|
||||
|
||||
function DocBody(props) {
|
||||
const {metadata, content} = props;
|
||||
const {metadata, content, docsMetadata} = props;
|
||||
const {language, version} = metadata;
|
||||
const context = useContext(DocusaurusContext);
|
||||
useEffect(() => {
|
||||
context.setContext({metadata});
|
||||
}, []);
|
||||
|
||||
const DocContents = content;
|
||||
return (
|
||||
|
@ -59,7 +54,7 @@ function DocBody(props) {
|
|||
</div>
|
||||
</article>
|
||||
<div className="margin-vert--lg">
|
||||
<DocsPaginator />
|
||||
<DocsPaginator docsMetadata={docsMetadata} metadata={metadata} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--3 col--offset-1">
|
||||
|
|
|
@ -5,17 +5,11 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React, {useContext} from 'react';
|
||||
import React from 'react';
|
||||
import Link from '@docusaurus/Link';
|
||||
|
||||
import DocusaurusContext from '@docusaurus/context';
|
||||
|
||||
function DocsPaginator() {
|
||||
const context = useContext(DocusaurusContext);
|
||||
const {docsMetadata, metadata} = context;
|
||||
if (!metadata || !docsMetadata) {
|
||||
return null;
|
||||
}
|
||||
function DocsPaginator(props) {
|
||||
const {docsMetadata, metadata} = props;
|
||||
const {docs} = docsMetadata;
|
||||
|
||||
return (
|
||||
|
|
|
@ -13,7 +13,8 @@ import DocusaurusContext from '@docusaurus/context';
|
|||
|
||||
function Navbar(props) {
|
||||
const context = useContext(DocusaurusContext);
|
||||
const {siteConfig = {}, env = {}, metadata = {}, docsMetadata} = context;
|
||||
const {siteConfig = {}, env = {}, metadata = {}} = context;
|
||||
// TODO: navbar headerlinks should depends on theme, not siteConfig;
|
||||
const {
|
||||
baseUrl,
|
||||
headerLinks,
|
||||
|
@ -31,46 +32,15 @@ function Navbar(props) {
|
|||
|
||||
// function to generate each header link
|
||||
const makeLinks = link => {
|
||||
if (link.languages) {
|
||||
// TODO in the future for <LanguageDropdown /> like in v1
|
||||
return null;
|
||||
}
|
||||
if (link.doc) {
|
||||
// set link to document with current page's language/version
|
||||
const langPart = translationEnabled ? `${thisLanguage}-` : '';
|
||||
const versionPart =
|
||||
versioningEnabled && thisVersion !== 'next'
|
||||
? `version-${thisVersion || env.versioning.defaultVersion}-`
|
||||
: '';
|
||||
const id = langPart + versionPart + link.doc;
|
||||
const {docs} = docsMetadata;
|
||||
if (!docs[id]) {
|
||||
const errorStr = `We could not find the doc with id: ${id}. Please check your headerLinks correctly\n`;
|
||||
throw new Error(errorStr);
|
||||
}
|
||||
|
||||
if (link.url) {
|
||||
// internal link
|
||||
const targetLink = `${baseUrl}${link.url}`;
|
||||
return (
|
||||
<div key={link.doc} className="navbar__item">
|
||||
<div key={targetLink} className="navbar__item">
|
||||
<Link
|
||||
activeClassName="navbar__link--active"
|
||||
className="navbar__link"
|
||||
to={docs[id].permalink}>
|
||||
{link.label}
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (link.page) {
|
||||
// set link to page with current page's language if appropriate
|
||||
const pageHref = `${baseUrl}${thisLanguage ? `${thisLanguage}/` : ''}${
|
||||
link.page
|
||||
}`;
|
||||
return (
|
||||
<div key={link.page} className="navbar__item">
|
||||
<Link
|
||||
activeClassName="navbar__link--active"
|
||||
className="navbar__link"
|
||||
to={pageHref}>
|
||||
to={targetLink}>
|
||||
{link.label}
|
||||
</Link>
|
||||
</div>
|
||||
|
@ -86,20 +56,6 @@ function Navbar(props) {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
if (link.blog) {
|
||||
// set link to blog url
|
||||
const blogUrl = `${baseUrl}blog`;
|
||||
return (
|
||||
<div key="Blog" className="navbar__item">
|
||||
<Link
|
||||
activeClassName="navbar__link--active"
|
||||
className="navbar__link"
|
||||
to={blogUrl}>
|
||||
Blog
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
|
|
@ -5,16 +5,17 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React, {useContext} from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import DocusaurusContext from '@docusaurus/context';
|
||||
import Link from '@docusaurus/Link';
|
||||
|
||||
import styles from './styles.module.css';
|
||||
|
||||
function Sidebar() {
|
||||
const context = useContext(DocusaurusContext);
|
||||
const {metadata = {}, docsMetadata} = context;
|
||||
function Sidebar(props) {
|
||||
const {docsMetadata, location} = props;
|
||||
|
||||
const id = docsMetadata.permalinkToId[location.pathname];
|
||||
const metadata = docsMetadata.docs[id] || {};
|
||||
const {sidebar, language} = metadata;
|
||||
|
||||
if (!sidebar) {
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const ejs = require('ejs');
|
||||
const fs = require('fs-extra');
|
||||
const _ = require('lodash');
|
||||
const path = require('path');
|
||||
|
||||
const {generate} = require('@docusaurus/utils');
|
||||
|
@ -41,11 +38,7 @@ module.exports = async function load(siteDir, cliOptions = {}) {
|
|||
// Process plugins.
|
||||
const pluginConfigs = siteConfig.plugins || [];
|
||||
const context = {env, siteDir, generatedFilesDir, siteConfig, cliOptions};
|
||||
const {
|
||||
plugins,
|
||||
pluginsRouteConfigs,
|
||||
pluginsLoadedContent,
|
||||
} = await loadPlugins({
|
||||
const {plugins, pluginsRouteConfigs} = await loadPlugins({
|
||||
pluginConfigs,
|
||||
context,
|
||||
});
|
||||
|
@ -61,8 +54,6 @@ module.exports = async function load(siteDir, cliOptions = {}) {
|
|||
registry,
|
||||
routesChunkNames,
|
||||
routesConfig,
|
||||
routesMetadata,
|
||||
routesMetadataPath,
|
||||
routesPaths,
|
||||
} = await loadRoutes(pluginsRouteConfigs);
|
||||
|
||||
|
@ -81,61 +72,14 @@ ${Object.keys(registry)
|
|||
.join('\n')}};\n`,
|
||||
);
|
||||
|
||||
/* Mapping of routePath -> moduleName -> required webpack chunk names.
|
||||
Example: {
|
||||
"/docs": {
|
||||
"component": "component---theme-doc-03d"
|
||||
}
|
||||
},
|
||||
*/
|
||||
await generate(
|
||||
generatedFilesDir,
|
||||
'routesChunkNames.json',
|
||||
JSON.stringify(routesChunkNames, null, 2),
|
||||
);
|
||||
|
||||
// Write out all the metadata JSON file
|
||||
await Promise.all(
|
||||
routesPaths.map(async routesPath => {
|
||||
const metadata = routesMetadata[routesPath] || {};
|
||||
const metadataPath = routesMetadataPath[routesPath];
|
||||
const metadataDir = path.join(generatedFilesDir, 'metadata');
|
||||
const fileName = metadataPath.replace(/^@generated\/metadata\//, '');
|
||||
await generate(metadataDir, fileName, JSON.stringify(metadata, null, 2));
|
||||
}),
|
||||
);
|
||||
|
||||
await generate(generatedFilesDir, 'routes.js', routesConfig);
|
||||
|
||||
// -------------------------- TBD (Experimental) ----------------------
|
||||
// TODO: we always assume that plugin loaded content always wanted to be imported globally
|
||||
// TODO: contentStore API
|
||||
// Generate contents metadata.
|
||||
const metadataTemplateFile = path.resolve(
|
||||
__dirname,
|
||||
'../../client/templates/metadata.template.ejs',
|
||||
);
|
||||
const metadataTemplate = fs.readFileSync(metadataTemplateFile).toString();
|
||||
const pluginMetadataImports = _.compact(pluginsLoadedContent).map(
|
||||
({metadataKey, contentPath}) => ({
|
||||
name: metadataKey,
|
||||
path: contentPath,
|
||||
}),
|
||||
);
|
||||
|
||||
const metadataFile = ejs.render(metadataTemplate, {
|
||||
imports: [
|
||||
...pluginMetadataImports,
|
||||
{
|
||||
name: 'env',
|
||||
path: '@generated/env',
|
||||
},
|
||||
],
|
||||
});
|
||||
await generate(generatedFilesDir, 'metadata.js', metadataFile);
|
||||
|
||||
// ------------- END OF TBD -----------------------------------------
|
||||
|
||||
const props = {
|
||||
siteConfig,
|
||||
siteDir,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const {generate, posixPath} = require('@docusaurus/utils');
|
||||
const {generate} = require('@docusaurus/utils');
|
||||
|
||||
module.exports = async function loadPlugins({pluginConfigs = [], context}) {
|
||||
// 1. Plugin Lifecycle - Initialization/Constructor
|
||||
|
@ -36,46 +36,34 @@ module.exports = async function loadPlugins({pluginConfigs = [], context}) {
|
|||
if (!plugin.loadContent) {
|
||||
return null;
|
||||
}
|
||||
const name = plugin.getName();
|
||||
const {options} = plugin;
|
||||
const {metadataKey, metadataFileName} = options;
|
||||
const content = await plugin.loadContent();
|
||||
const pluginContentPath = path.join(name, metadataFileName);
|
||||
const pluginContentDir = path.join(context.generatedFilesDir, name);
|
||||
await fs.ensureDir(pluginContentDir);
|
||||
await generate(
|
||||
pluginContentDir,
|
||||
metadataFileName,
|
||||
JSON.stringify(content, null, 2),
|
||||
);
|
||||
// Note that we need to convert it into POSIX format because
|
||||
// import XXXXX from '@generated\this-is\my\path' is incorrect
|
||||
// import XXXXX from '@generated/this-is/my/path' is correct
|
||||
const contentPath = posixPath(path.join('@generated', pluginContentPath));
|
||||
|
||||
return {
|
||||
metadataKey,
|
||||
contentPath,
|
||||
content,
|
||||
};
|
||||
return content;
|
||||
}),
|
||||
);
|
||||
|
||||
// 3. Plugin lifecycle - contentLoaded
|
||||
const pluginsRouteConfigs = [];
|
||||
|
||||
const actions = {
|
||||
addRoute: config => pluginsRouteConfigs.push(config),
|
||||
};
|
||||
|
||||
await Promise.all(
|
||||
plugins.map(async (plugin, index) => {
|
||||
if (!plugin.contentLoaded) {
|
||||
return;
|
||||
}
|
||||
const pluginName = plugin.getName();
|
||||
const pluginContentDir = path.join(context.generatedFilesDir, pluginName);
|
||||
const actions = {
|
||||
addRoute: config => pluginsRouteConfigs.push(config),
|
||||
createData: async (name, content) => {
|
||||
const modulePath = path.join(pluginContentDir, name);
|
||||
await fs.ensureDir(path.dirname(modulePath));
|
||||
await generate(pluginContentDir, name, content);
|
||||
return modulePath;
|
||||
},
|
||||
};
|
||||
|
||||
const loadedContent = pluginsLoadedContent[index];
|
||||
await plugin.contentLoaded({
|
||||
content: loadedContent.content,
|
||||
content: loadedContent,
|
||||
actions,
|
||||
});
|
||||
}),
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const {genChunkName, docuHash} = require('@docusaurus/utils');
|
||||
const {genChunkName} = require('@docusaurus/utils');
|
||||
const {stringify} = require('querystring');
|
||||
const _ = require('lodash');
|
||||
|
||||
|
@ -14,27 +14,11 @@ async function loadRoutes(pluginsRouteConfigs) {
|
|||
`import React from 'react';`,
|
||||
`import ComponentCreator from '@docusaurus/ComponentCreator';`,
|
||||
];
|
||||
// Routes paths. Example: ['/', '/docs', '/blog/2017/09/03/test']
|
||||
const routesPaths = [];
|
||||
const addRoutesPath = routePath => {
|
||||
routesPaths.push(routePath);
|
||||
};
|
||||
|
||||
// Mapping of routePath -> metadataPath. Example: '/blog' -> '@generated/metadata/blog-c06.json'
|
||||
const routesMetadataPath = {};
|
||||
const addRoutesMetadataPath = routePath => {
|
||||
const fileName = `${docuHash(routePath)}.json`;
|
||||
routesMetadataPath[routePath] = `@generated/metadata/${fileName}`;
|
||||
};
|
||||
|
||||
// Mapping of routePath -> metadata. Example: '/blog' -> { isBlogPage: true, permalink: '/blog' }
|
||||
const routesMetadata = {};
|
||||
const addRoutesMetadata = (routePath, metadata) => {
|
||||
if (metadata) {
|
||||
routesMetadata[routePath] = metadata;
|
||||
}
|
||||
};
|
||||
|
||||
const registry = {};
|
||||
|
||||
const routesChunkNames = {};
|
||||
|
@ -54,21 +38,17 @@ async function loadRoutes(pluginsRouteConfigs) {
|
|||
const {
|
||||
path: routePath,
|
||||
component,
|
||||
metadata,
|
||||
modules = {},
|
||||
routes,
|
||||
exact,
|
||||
} = routeConfig;
|
||||
|
||||
addRoutesPath(routePath);
|
||||
addRoutesMetadata(routePath, metadata);
|
||||
addRoutesMetadataPath(routePath);
|
||||
|
||||
// Given an input (object or string), get the import path str
|
||||
const getModulePath = target => {
|
||||
const importStr = _.isObject(target) ? target.path : target;
|
||||
const queryStr = target.query ? `?${stringify(target.query)}` : '';
|
||||
|
||||
return `${importStr}${queryStr}`;
|
||||
};
|
||||
|
||||
|
@ -117,12 +97,6 @@ async function loadRoutes(pluginsRouteConfigs) {
|
|||
|
||||
_.assign(routesChunkNames[routePath], genRouteChunkNames(modules));
|
||||
|
||||
if (metadata) {
|
||||
const metadataPath = routesMetadataPath[routePath];
|
||||
const metadataChunk = genImportChunk(metadataPath, 'metadata', routePath);
|
||||
addRoutesChunkNames(routePath, 'metadata', metadataChunk);
|
||||
}
|
||||
|
||||
const routesStr = routes
|
||||
? `routes: [${routes.map(generateRouteCode).join(',')}],`
|
||||
: '';
|
||||
|
@ -156,8 +130,6 @@ export default [
|
|||
registry,
|
||||
routesConfig,
|
||||
routesChunkNames,
|
||||
routesMetadata,
|
||||
routesMetadataPath,
|
||||
routesPaths,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,13 +13,9 @@ module.exports = {
|
|||
baseUrl: '/',
|
||||
url: 'https://docusaurus-2.netlify.com',
|
||||
headerLinks: [
|
||||
{doc: 'installation', label: 'Docs'},
|
||||
{page: 'youtube', label: 'Youtube'},
|
||||
{blog: true, label: 'Blog'},
|
||||
{
|
||||
href: 'https://github.com/facebook/docusaurus',
|
||||
label: 'GitHub',
|
||||
},
|
||||
{url: 'docs/installation', label: 'Docs'},
|
||||
{url: 'blog', label: 'Blog'},
|
||||
{url: 'feedback/', label: 'Feedback'},
|
||||
],
|
||||
headerIcon: 'img/docusaurus.svg',
|
||||
favicon: 'img/docusaurus.ico',
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
"@docusaurus/plugin-sitemap": "^2.0.0-alpha.11",
|
||||
"classnames": "^2.2.6",
|
||||
"react": "^16.8.4",
|
||||
"react-dom": "^16.8.4",
|
||||
"react-youtube": "^7.9.0"
|
||||
"react-dom": "^16.8.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
/* eslint-disable */
|
||||
import React from 'react';
|
||||
import Head from '@docusaurus/Head';
|
||||
import YouTube from 'react-youtube';
|
||||
|
||||
export default class Player extends React.Component {
|
||||
render() {
|
||||
const opts = {
|
||||
height: '390',
|
||||
width: '640',
|
||||
playerVars: {
|
||||
autoplay: 1,
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Head>
|
||||
<title>My Youtube</title>
|
||||
</Head>
|
||||
<div className="container margin-vert--xl text--center">
|
||||
{/* this is a React-youtube component */}
|
||||
<YouTube videoId="d9IxdwEFk1c" opts={opts} onReady={this._onReady} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
_onReady(event) {
|
||||
// access to player in all event handlers via event.target
|
||||
event.target.playVideo();
|
||||
}
|
||||
}
|
25
yarn.lock
25
yarn.lock
|
@ -10649,7 +10649,7 @@ promzard@^0.3.0:
|
|||
dependencies:
|
||||
read "1"
|
||||
|
||||
prop-types@^15.5.0, prop-types@^15.5.3, prop-types@^15.5.4, prop-types@^15.6.2:
|
||||
prop-types@^15.5.0, prop-types@^15.5.4, prop-types@^15.6.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
|
@ -11027,15 +11027,6 @@ react-side-effect@^1.1.0:
|
|||
exenv "^1.2.1"
|
||||
shallowequal "^1.0.1"
|
||||
|
||||
react-youtube@^7.9.0:
|
||||
version "7.9.0"
|
||||
resolved "https://registry.yarnpkg.com/react-youtube/-/react-youtube-7.9.0.tgz#cf513c253581e1e45aa412a77d03420dfd7f7ba7"
|
||||
integrity sha512-2+nBF4qP8nStYEILIO1/SylKOCnnJUxuZm+qCeWA0eeZxnWZIIixfAeAqbzblwx5L1n/26ACocy3epm9Glox8w==
|
||||
dependencies:
|
||||
fast-deep-equal "^2.0.1"
|
||||
prop-types "^15.5.3"
|
||||
youtube-player "^5.5.1"
|
||||
|
||||
react@^16.5.0, react@^16.8.4:
|
||||
version "16.8.5"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.8.5.tgz#49be3b655489d74504ad994016407e8a0445de66"
|
||||
|
@ -11995,11 +11986,6 @@ simple-swizzle@^0.2.2:
|
|||
dependencies:
|
||||
is-arrayish "^0.3.1"
|
||||
|
||||
sister@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/sister/-/sister-3.0.1.tgz#a36ba6a1d1e46415ba16cb4ecefe14cbd8d82d1f"
|
||||
integrity sha512-aG41gNRHRRxPq52MpX4vtm9tapnr6ENmHUx8LMAJWCOplEMwXzh/dp5WIo52Wl8Zlc/VUyHLJ2snX0ck+Nma9g==
|
||||
|
||||
sisteransi@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.0.tgz#77d9622ff909080f1c19e5f4a1df0c1b0a27b88c"
|
||||
|
@ -14021,15 +14007,6 @@ yauzl@^2.4.2:
|
|||
buffer-crc32 "~0.2.3"
|
||||
fd-slicer "~1.1.0"
|
||||
|
||||
youtube-player@^5.5.1:
|
||||
version "5.5.2"
|
||||
resolved "https://registry.yarnpkg.com/youtube-player/-/youtube-player-5.5.2.tgz#052b86b1eabe21ff331095ffffeae285fa7f7cb5"
|
||||
integrity sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ==
|
||||
dependencies:
|
||||
debug "^2.6.6"
|
||||
load-script "^1.0.0"
|
||||
sister "^3.0.0"
|
||||
|
||||
zepto@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/zepto/-/zepto-1.2.0.tgz#e127bd9e66fd846be5eab48c1394882f7c0e4f98"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue