From dc0c1390c469c6f7fb956f55ecd81ba39165414b Mon Sep 17 00:00:00 2001 From: Joel Marcey Date: Wed, 8 Nov 2017 20:16:05 -0800 Subject: [PATCH 1/3] [WIP] Allow custom subpath for docs within the "docs" folder e.g., The default is `docs/*.md` This allows `docs/somedir/*.md` or `docs/somedir/anotherdir/*.md` Notes: - All URLs are still /docs/*.html (i.e. the subpath does not get preserved in the link). - Files in `translated_docs`, if any, will still only be one level - This should not affect translations or versioning --- lib/server/generate.js | 6 +++--- lib/server/readMetadata.js | 20 ++++++++++++++++---- lib/server/server.js | 4 ++-- lib/version.js | 2 +- lib/write-translations.js | 4 ++-- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/server/generate.js b/lib/server/generate.js index b919651f26..262af55979 100644 --- a/lib/server/generate.js +++ b/lib/server/generate.js @@ -129,7 +129,7 @@ function execute() { } } else { if (metadata.language === "en") { - file = CWD + "/../docs/" + metadata.source; + file = CWD + "/../" + readMetadata.getDocsPath() + "/" + metadata.source; } else { file = CWD + "/translated_docs/" + metadata.language + "/" + metadata.source; @@ -219,9 +219,9 @@ function execute() { }); // copy docs assets if they exist - if (fs.existsSync(CWD + "/../docs/assets")) { + if (fs.existsSync(CWD + "/../" + readMetadata.getDocsPath() + "/assets")) { fs.copySync( - CWD + "/../docs/assets", + CWD + "/../" + readMetadata.getDocsPath() + "/assets", CWD + "/build/" + siteConfig.projectName + "/docs/assets" ); } diff --git a/lib/server/readMetadata.js b/lib/server/readMetadata.js index 2d7421e261..a24780c670 100644 --- a/lib/server/readMetadata.js +++ b/lib/server/readMetadata.js @@ -16,6 +16,8 @@ const versionFallback = require("./versionFallback.js"); const ENABLE_VERSIONING = fs.existsSync(CWD + "/versions.json"); + + let languages; if (fs.existsSync(CWD + "/languages.js")) { languages = require(CWD + "/languages.js"); @@ -29,6 +31,15 @@ if (fs.existsSync(CWD + "/languages.js")) { ]; } +// Can add additional path information to the docs folder +// e.g., docs/whereDocsReallyExist +// All .md docs still (currently) must be in one flat directory hierarchy. +// e.g., docs/whereDocsReallyExist/*.md (all .md files in this dir) +function getDocsPath() { + return siteConfig.docsAdditionalPath + ? "docs" + siteConfig.docsAdditionalPath + : "docs"; +} // returns map from id to object containing sidebar ordering info function readSidebar() { let allSidebars; @@ -114,7 +125,7 @@ function extractMetadata(content) { function processMetadata(file) { const result = extractMetadata(fs.readFileSync(file, "utf8")); - const regexSubFolder = /docs\/(.*)\/.*/; + let regexSubFolder = new RegExp("/" + getDocsPath() + "\/(.*)\/.*/"); let language = "en"; const match = regexSubFolder.exec(file); @@ -190,7 +201,7 @@ function generateMetadataDocs() { console.error(e); process.exit(1); } - + const regexSubFolder = /translated_docs\/(.*)\/.*/; const enabledLanguages = []; @@ -202,7 +213,7 @@ function generateMetadataDocs() { const defaultMetadatas = {}; // metadata for english files - let files = glob.sync(CWD + "/../docs/**"); + let files = glob.sync(CWD + "/../" + getDocsPath() + "/**"); files.forEach(file => { let language = "en"; @@ -210,7 +221,7 @@ function generateMetadataDocs() { if (extension === ".md" || extension === ".markdown") { const res = processMetadata(file); - + if (!res) { return; } @@ -389,6 +400,7 @@ function generateMetadataBlog() { } module.exports = { + getDocsPath, readSidebar, extractMetadata, processMetadata, diff --git a/lib/server/server.js b/lib/server/server.js index 5585e47f63..684a4e14e2 100644 --- a/lib/server/server.js +++ b/lib/server/server.js @@ -177,7 +177,7 @@ function execute(port) { } } else { if (metadata.language === "en") { - file = CWD + "/../docs/" + metadata.source; + file = CWD + "/../" + readMetadata.getDocsPath() + "/" + metadata.source; } else { file = CWD + "/translated_docs/" + metadata.language + "/" + metadata.source; @@ -485,7 +485,7 @@ function execute(port) { // serve static assets from these locations app.use( siteConfig.baseUrl + "docs/assets/", - express.static(CWD + "/../docs/assets") + express.static(CWD + "/../" + readMetadata.getDocsPath() + "/assets") ); app.use( siteConfig.baseUrl + "blog/assets/", diff --git a/lib/version.js b/lib/version.js index 429aac1928..b1e003da92 100755 --- a/lib/version.js +++ b/lib/version.js @@ -65,7 +65,7 @@ const versionFolder = CWD + "/versioned_docs/version-" + version; mkdirp.sync(versionFolder); // copy necessary files to new version, changing some of its metadata to reflect the versioning -let files = glob.sync(CWD + "/../docs/*"); +let files = glob.sync(CWD + "/../" + readMetadata.getDocsPath() + "/*"); files.forEach(file => { const ext = path.extname(file); if (ext !== ".md" && ext !== ".markdown") { diff --git a/lib/write-translations.js b/lib/write-translations.js index 117501ff02..b973c74a88 100755 --- a/lib/write-translations.js +++ b/lib/write-translations.js @@ -48,7 +48,7 @@ function execute() { }; // look through markdown headers of docs for titles and categories to translate - let files = glob.sync(CWD + "/../docs/**"); + let files = glob.sync(CWD + "/../" + readMetadata.getDocsPath() + "/**"); files.forEach(file => { const extension = path.extname(file); if (extension === ".md" || extension === ".markdown") { @@ -91,7 +91,7 @@ function execute() { files.forEach(file => { if (!file.endsWith("-sidebars.json")) { if (file.endsWith("-sidebar.json")) { - console.warn(`Skipping ${file}. Make sure your sidebar filenames follow this format: 'version-VERSION-sidebars.json'.`); + console.warn(`Skipping ${file}. Make sure your sidebar filenames follow this format: 'version-VERSION-sidebars.json'.`); } return; } From e273dfc13b4031d4d20180d0de30b1c5280d2bf8 Mon Sep 17 00:00:00 2001 From: Joel Marcey Date: Thu, 9 Nov 2017 09:55:26 -0800 Subject: [PATCH 2/3] Allow the docs not to just be in a folder called `docs` Also: - regex escaping - update api documentation --- docs/api-site-config.md | 10 ++++++++++ lib/core/nav/HeaderNav.js | 10 ++++++---- lib/server/readMetadata.js | 11 +++++++---- package.json | 1 + website/siteConfig.js | 2 +- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/docs/api-site-config.md b/docs/api-site-config.md index e5619476e1..bd8f9e6bf1 100644 --- a/docs/api-site-config.md +++ b/docs/api-site-config.md @@ -62,6 +62,16 @@ headerLinks: [ ### Optional Fields +`customDocsPath` - By default, Docusaurus expects your documentation to be in a directory called `docs`. This directory is at the same level as the `website` directory (i.e., not inside the `website` directory). You can specify a custom path to your documentation with this field. **Note that all of your documentation *.md files must still reside in a flat hierarchy. You cannot have your documents in nested directories**. + +```js +customDocsPath: "docs/site" +``` + +```js +customDocsPath: "website-docs" +``` + `editUrl` - url for editing docs, usage example: `editUrl + 'en/doc1.md'`. If this field is omitted, there will be no "Edit this Doc" button for each document. `users` - The `users` array mentioned earlier. diff --git a/lib/core/nav/HeaderNav.js b/lib/core/nav/HeaderNav.js index 8af4230554..baa0a3cf0b 100644 --- a/lib/core/nav/HeaderNav.js +++ b/lib/core/nav/HeaderNav.js @@ -21,7 +21,8 @@ let versions; if (ENABLE_VERSIONING) { versions = require(CWD + "/versions.json"); } -require("../../server/readMetadata.js").generateMetadataDocs(); +const readMetadata = require("../../server/readMetadata.js"); +readMetadata.generateMetadataDocs(); const Metadata = require("../metadata.js"); // language dropdown nav item for when translations are enabled @@ -221,9 +222,10 @@ class HeaderNav extends React.Component { } let search = false; headerLinks.forEach(link => { - if (link.doc && !fs.existsSync(CWD + "/../docs/")) { + if (link.doc && !fs.existsSync(CWD + "/../" + readMetadata.getDocsPath() + "/")) { throw new Error( - "You have 'doc' in your headerLinks, but no 'docs' folder exists one level up from " + + "You have 'doc' in your headerLinks, but no '" + readMetadata.getDocsPath() + + "' folder exists one level up from " + "'website' folder. Did you run `docusaurus-init` or `npm run examples`? If so, " + "make sure you rename 'docs-examples-from-docusaurus' to 'docs'." ); @@ -231,7 +233,7 @@ class HeaderNav extends React.Component { if (link.blog && !fs.existsSync(CWD + "/blog/")) { throw new Error( "You have 'blog' in your headerLinks, but no 'blog' folder exists in your " + - "website folder. Did you run `docusaurus-init` or `npm run examples`? If so, " + + "'website' folder. Did you run `docusaurus-init` or `npm run examples`? If so, " + "make sure you rename 'blog-examples-from-docusaurus' to 'blog'." ); } diff --git a/lib/server/readMetadata.js b/lib/server/readMetadata.js index a24780c670..d4ebeca7ec 100644 --- a/lib/server/readMetadata.js +++ b/lib/server/readMetadata.js @@ -13,6 +13,7 @@ const glob = require("glob"); const chalk = require("chalk"); const siteConfig = require(CWD + "/siteConfig.js"); const versionFallback = require("./versionFallback.js"); +const escapeStringRegexp = require("escape-string-regexp"); const ENABLE_VERSIONING = fs.existsSync(CWD + "/versions.json"); @@ -31,13 +32,15 @@ if (fs.existsSync(CWD + "/languages.js")) { ]; } -// Can add additional path information to the docs folder +// Can have a custom docs path. Top level folder still needs to be in directory +// at the same level as `website`, not inside `website`. // e.g., docs/whereDocsReallyExist +// website-docs/ // All .md docs still (currently) must be in one flat directory hierarchy. // e.g., docs/whereDocsReallyExist/*.md (all .md files in this dir) function getDocsPath() { - return siteConfig.docsAdditionalPath - ? "docs" + siteConfig.docsAdditionalPath + return siteConfig.customDocsPath + ? siteConfig.customDocsPath : "docs"; } // returns map from id to object containing sidebar ordering info @@ -125,7 +128,7 @@ function extractMetadata(content) { function processMetadata(file) { const result = extractMetadata(fs.readFileSync(file, "utf8")); - let regexSubFolder = new RegExp("/" + getDocsPath() + "\/(.*)\/.*/"); + let regexSubFolder = new RegExp("/" + escapeStringRegexp(getDocsPath()) + "\/(.*)\/.*/"); let language = "en"; const match = regexSubFolder.exec(file); diff --git a/package.json b/package.json index 4c4da70293..ba531d8d1c 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "commander": "^2.11.0", "crowdin-cli": "^0.3.0", "diff": "^3.3.0", + "escape-string-regexp": "^1.0.5", "express": "^4.15.3", "feed": "^1.1.0", "fs-extra": "^3.0.1", diff --git a/website/siteConfig.js b/website/siteConfig.js index dd24bd38e8..d2c15c9111 100644 --- a/website/siteConfig.js +++ b/website/siteConfig.js @@ -68,7 +68,7 @@ const siteConfig = { copyright: "Copyright © " + new Date().getFullYear() + " Facebook Inc.", highlight: { theme: "solarized-dark" - } + }, }; From 7e47fe2e9171530274312decda649a4f21330df6 Mon Sep 17 00:00:00 2001 From: Joel Marcey Date: Thu, 9 Nov 2017 09:59:27 -0800 Subject: [PATCH 3/3] Remove spurious comma from siteConfig.js --- website/siteConfig.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/siteConfig.js b/website/siteConfig.js index d2c15c9111..dd24bd38e8 100644 --- a/website/siteConfig.js +++ b/website/siteConfig.js @@ -68,7 +68,7 @@ const siteConfig = { copyright: "Copyright © " + new Date().getFullYear() + " Facebook Inc.", highlight: { theme: "solarized-dark" - }, + } };