From 64b3d7143618699088a66b72fe205d93e59e8b5a Mon Sep 17 00:00:00 2001 From: endiliey Date: Sun, 27 May 2018 01:13:35 +0800 Subject: [PATCH 01/11] enable subdirectory for docs --- docs/test/feature.md | 6 ++++++ lib/core/DocsLayout.js | 25 +++++++++++++++++++------ lib/server/readMetadata.js | 9 +++++++++ website/sidebars.json | 3 +++ 4 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 docs/test/feature.md diff --git a/docs/test/feature.md b/docs/test/feature.md new file mode 100644 index 000000000000..8fe5cbc782df --- /dev/null +++ b/docs/test/feature.md @@ -0,0 +1,6 @@ +--- +id: feature +title: Sub-directory Test +--- + +Testing subdirectory diff --git a/lib/core/DocsLayout.js b/lib/core/DocsLayout.js index 5889511637b3..7f5b0ad7a2f2 100644 --- a/lib/core/DocsLayout.js +++ b/lib/core/DocsLayout.js @@ -28,6 +28,23 @@ class DocsLayout extends React.Component { this.props.metadata.localized_id ] || this.props.metadata.title : this.props.metadata.title; + const prevDir = + metadata.previous_id && metadata.previous_id.includes('/') + ? metadata.previous_id.split('/')[0] + : '.'; + const curDir = metadata.id.includes('/') ? metadata.id.split('/')[0] : '.'; + const nextDir = + metadata.next_id && metadata.next_id.includes('/') + ? metadata.next_id.split('/')[0] + : '.'; + let prevLink = metadata.previous_id + '.html'; + if (prevDir !== curDir && curDir != '.') { + prevLink = '../' + prevLink; + } + let nextLink = metadata.next_id + '.html'; + if (nextDir !== curDir && curDir != '.') { + nextLink = '../' + nextLink; + } return (
{metadata.previous_id && ( - + ←{' '} {i18n ? translation[this.props.metadata.language][ @@ -68,9 +83,7 @@ class DocsLayout extends React.Component { )} {metadata.next_id && ( - + {i18n ? translation[this.props.metadata.language][ 'localized-strings' diff --git a/lib/server/readMetadata.js b/lib/server/readMetadata.js index fd1e24551fc8..0e61af555fbe 100644 --- a/lib/server/readMetadata.js +++ b/lib/server/readMetadata.js @@ -150,6 +150,15 @@ function processMetadata(file) { if (metadata.id.includes('/')) { throw new Error('Document id cannot include "/".'); } + + // if file is located in subdirectory, + // it will have the directory name appended to it's id + const curDir = path.dirname(file.split(getDocsPath() + '/')[1]); + if (curDir !== '.') { + metadata.id = curDir + '/' + metadata.id; + metadata.source = curDir + '/' + metadata.source; + } + if (!metadata.title) { metadata.title = metadata.id; } diff --git a/website/sidebars.json b/website/sidebars.json index 0f3f0d6ee983..28523252a0d2 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -19,6 +19,9 @@ "doc-markdown", "api-pages", "site-config" + ], + "Test": [ + "test/feature" ] } } From b386c732e93888baa1d7b1a26f96b035a0f1396b Mon Sep 17 00:00:00 2001 From: endiliey Date: Sun, 27 May 2018 01:29:05 +0800 Subject: [PATCH 02/11] modify test to include subdir doc --- lib/__tests__/build-files.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/__tests__/build-files.test.js b/lib/__tests__/build-files.test.js index fe92052e7b54..6953eddc8db4 100644 --- a/lib/__tests__/build-files.test.js +++ b/lib/__tests__/build-files.test.js @@ -42,7 +42,7 @@ beforeAll(() => { generateSite(); return Promise.all([ glob(docsDir + '/**/*.md'), - glob(buildDir + '/' + siteConfig.projectName + '/docs/*.html'), + glob(buildDir + '/' + siteConfig.projectName + '/docs/**/*.html'), glob(docsDir + '/assets/*'), glob(buildDir + '/' + siteConfig.projectName + '/img/*'), ]).then(function(results) { From a9078092c5473794546058cd6060defeb4d085d8 Mon Sep 17 00:00:00 2001 From: endiliey Date: Thu, 31 May 2018 11:52:49 +0800 Subject: [PATCH 03/11] re-implement to support nested subdirectories --- docs/projectA/README.md | 10 ++++++++++ docs/projectA/docs/architecture.md | 8 ++++++++ docs/projectA/docs/contributors.md | 8 ++++++++ docs/projectB/guides/install.md | 15 +++++++++++++++ docs/test/feature.md | 6 ------ lib/server/readMetadata.js | 19 +++++++++++++++++-- lib/server/server.js | 2 +- website/sidebars.json | 9 +++++++-- 8 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 docs/projectA/README.md create mode 100644 docs/projectA/docs/architecture.md create mode 100644 docs/projectA/docs/contributors.md create mode 100644 docs/projectB/guides/install.md delete mode 100644 docs/test/feature.md diff --git a/docs/projectA/README.md b/docs/projectA/README.md new file mode 100644 index 000000000000..b3804fea7a2f --- /dev/null +++ b/docs/projectA/README.md @@ -0,0 +1,10 @@ +--- +id: readme +title: README +--- + +## Docs +Welcome to Project A, here are some available docs + +1. [Architecture](projectA/docs/architecture.md) +2. [Contributors](projectA/docs/contributors.md) diff --git a/docs/projectA/docs/architecture.md b/docs/projectA/docs/architecture.md new file mode 100644 index 000000000000..6c606556b462 --- /dev/null +++ b/docs/projectA/docs/architecture.md @@ -0,0 +1,8 @@ +--- +id: architecture +title: Architecture +--- + +## Lorem ipsum + +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. diff --git a/docs/projectA/docs/contributors.md b/docs/projectA/docs/contributors.md new file mode 100644 index 000000000000..85b4ccb96d7c --- /dev/null +++ b/docs/projectA/docs/contributors.md @@ -0,0 +1,8 @@ +--- +id: contributors +title: Contributors +--- + +![Introducing Slash](/img/slash-introducing.png) + +But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure diff --git a/docs/projectB/guides/install.md b/docs/projectB/guides/install.md new file mode 100644 index 000000000000..92d733590001 --- /dev/null +++ b/docs/projectB/guides/install.md @@ -0,0 +1,15 @@ +--- +id: install +title: Install +--- + +Project B was designed from the ground up to be easily installed and used to get your website up and running quickly. + +### Launching the server behind a proxy + +If you are behind a corporate proxy, you need to disable it for the development server requests. It can be done using the `NO_PROXY` environment variable. + +```sh +SET NO_PROXY=localhost +yarn start (or npm run start) +``` diff --git a/docs/test/feature.md b/docs/test/feature.md deleted file mode 100644 index 8fe5cbc782df..000000000000 --- a/docs/test/feature.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -id: feature -title: Sub-directory Test ---- - -Testing subdirectory diff --git a/lib/server/readMetadata.js b/lib/server/readMetadata.js index 0e61af555fbe..61e2582e5672 100644 --- a/lib/server/readMetadata.js +++ b/lib/server/readMetadata.js @@ -130,7 +130,18 @@ function processMetadata(file) { ); const match = regexSubFolder.exec(file); - let language = match ? match[1] : 'en'; + let language = 'en'; + + // Avoid misinterpreting subdirectory as language + if (match && env.translation.enabled) { + const enabledLanguages = env.translation + .enabledLanguages() + .map(language => language.tag); + + if (enabledLanguages.indexOf(match[1]) !== -1) { + language = match[1]; + } + } const metadata = {}; for (const fieldName of Object.keys(result.metadata)) { @@ -153,7 +164,11 @@ function processMetadata(file) { // if file is located in subdirectory, // it will have the directory name appended to it's id - const curDir = path.dirname(file.split(getDocsPath() + '/')[1]); + const relativeFile = path.relative( + path.join(CWD, '../', getDocsPath()), + file + ); + const curDir = path.dirname(relativeFile); if (curDir !== '.') { metadata.id = curDir + '/' + metadata.id; metadata.source = curDir + '/' + metadata.source; diff --git a/lib/server/server.js b/lib/server/server.js index 47e0db30db7c..5a9c9e194905 100644 --- a/lib/server/server.js +++ b/lib/server/server.js @@ -130,7 +130,7 @@ function execute(port) { // handle all requests for document pages const app = express(); - app.get(/docs\/.*html$/, (req, res, next) => { + app.get(/^\/docs\/.*html$/, (req, res, next) => { let url = req.path.toString().replace(siteConfig.baseUrl, ''); // links is a map from a permalink to an id for each document diff --git a/website/sidebars.json b/website/sidebars.json index 28523252a0d2..b51da90e99cc 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -20,8 +20,13 @@ "api-pages", "site-config" ], - "Test": [ - "test/feature" + "Project A": [ + "projectA/readme", + "projectA/docs/architecture", + "projectA/docs/contributors" + ], + "Project B": [ + "projectB/guides/install" ] } } From dab7f38e4100bddeef54dd3ccb2e0e1847227ac3 Mon Sep 17 00:00:00 2001 From: endiliey Date: Thu, 31 May 2018 16:24:07 +0800 Subject: [PATCH 04/11] implement relative path builder in docslayout next/prev --- lib/core/DocsLayout.js | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/lib/core/DocsLayout.js b/lib/core/DocsLayout.js index 7f5b0ad7a2f2..7f250f1a779f 100644 --- a/lib/core/DocsLayout.js +++ b/lib/core/DocsLayout.js @@ -12,6 +12,7 @@ const DocsSidebar = require('./DocsSidebar.js'); const OnPageNav = require('./nav/OnPageNav.js'); const Site = require('./Site.js'); const translation = require('../server/translation.js'); +const path = require('path'); // component used to generate whole webpage for docs, including sidebar/header/footer class DocsLayout extends React.Component { @@ -28,23 +29,6 @@ class DocsLayout extends React.Component { this.props.metadata.localized_id ] || this.props.metadata.title : this.props.metadata.title; - const prevDir = - metadata.previous_id && metadata.previous_id.includes('/') - ? metadata.previous_id.split('/')[0] - : '.'; - const curDir = metadata.id.includes('/') ? metadata.id.split('/')[0] : '.'; - const nextDir = - metadata.next_id && metadata.next_id.includes('/') - ? metadata.next_id.split('/')[0] - : '.'; - let prevLink = metadata.previous_id + '.html'; - if (prevDir !== curDir && curDir != '.') { - prevLink = '../' + prevLink; - } - let nextLink = metadata.next_id + '.html'; - if (nextDir !== curDir && curDir != '.') { - nextLink = '../' + nextLink; - } return (
{metadata.previous_id && ( - + ←{' '} {i18n ? translation[this.props.metadata.language][ @@ -83,7 +73,13 @@ class DocsLayout extends React.Component { )} {metadata.next_id && ( - + {i18n ? translation[this.props.metadata.language][ 'localized-strings' From 29c2e213901ddf6142d0ab77685987f3edcbad82 Mon Sep 17 00:00:00 2001 From: endiliey Date: Thu, 31 May 2018 16:41:57 +0800 Subject: [PATCH 05/11] refactor & add comment --- lib/server/readMetadata.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/server/readMetadata.js b/lib/server/readMetadata.js index 61e2582e5672..f6cd8aad8d81 100644 --- a/lib/server/readMetadata.js +++ b/lib/server/readMetadata.js @@ -162,13 +162,11 @@ function processMetadata(file) { throw new Error('Document id cannot include "/".'); } - // if file is located in subdirectory, - // it will have the directory name appended to it's id - const relativeFile = path.relative( - path.join(CWD, '../', getDocsPath()), - file + // If a doc file is located in a subdirectory, prepend the subdir to it's ID + // Example: `docs/projectA/test.md` with 'test' ID is changed to `projectA/test` + const curDir = path.dirname( + path.relative(path.join(CWD, '../', getDocsPath()), file) ); - const curDir = path.dirname(relativeFile); if (curDir !== '.') { metadata.id = curDir + '/' + metadata.id; metadata.source = curDir + '/' + metadata.source; From f5d8f66295d3931952c621b24197c573d5d94f2b Mon Sep 17 00:00:00 2001 From: endiliey Date: Fri, 1 Jun 2018 18:57:32 +0800 Subject: [PATCH 06/11] refactor again & comment --- lib/server/readMetadata.js | 25 ++++++++++++++++++------- lib/server/versionFallback.js | 28 +++++++++++++++++++++++++++- lib/version.js | 21 ++++++++++++++++++--- 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/lib/server/readMetadata.js b/lib/server/readMetadata.js index f6cd8aad8d81..588768040cd9 100644 --- a/lib/server/readMetadata.js +++ b/lib/server/readMetadata.js @@ -121,6 +121,15 @@ function extractMetadata(content) { return {metadata, rawContent: both.content}; } +// Return the subdirectory path of a doc file +// Example: `docs/projectA/test.md` subDir is `projectA` +function getSubDir(file) { + const subDir = path.dirname( + path.relative(path.join(CWD, '../', getDocsPath()), file) + ); + return subDir !== '.' ? subDir : null; +} + // process the metadata for a document found in the docs folder function processMetadata(file) { const result = extractMetadata(fs.readFileSync(file, 'utf8')); @@ -153,7 +162,6 @@ function processMetadata(file) { } const rawContent = result.rawContent; - metadata.source = path.basename(file); if (!metadata.id) { metadata.id = path.basename(file, path.extname(file)); @@ -164,14 +172,16 @@ function processMetadata(file) { // If a doc file is located in a subdirectory, prepend the subdir to it's ID // Example: `docs/projectA/test.md` with 'test' ID is changed to `projectA/test` - const curDir = path.dirname( - path.relative(path.join(CWD, '../', getDocsPath()), file) - ); - if (curDir !== '.') { - metadata.id = curDir + '/' + metadata.id; - metadata.source = curDir + '/' + metadata.source; + const subDir = getSubDir(file); + if (subDir) { + metadata.id = subDir + '/' + metadata.id; } + // Example: `docs/projectA/test.md` source is `projectA/test.md` + metadata.source = subDir + ? subDir + '/' + path.basename(file) + : path.basename(file); + if (!metadata.title) { metadata.title = metadata.id; } @@ -433,6 +443,7 @@ function generateMetadataBlog() { module.exports = { getDocsPath, + getSubDir, readSidebar, extractMetadata, processMetadata, diff --git a/lib/server/versionFallback.js b/lib/server/versionFallback.js index 099fcb12388d..b9b5cf041d53 100644 --- a/lib/server/versionFallback.js +++ b/lib/server/versionFallback.js @@ -190,11 +190,37 @@ function diffLatestDoc(file, id) { ); } +// Return the subdirectory path of a versioned_doc file +// Example: `versioned_docs/version-1.0.11/projectA/test.md` subDir is `projectA` +function getSubDir(file, version) { + const subDir = path.dirname( + path.relative(path.join(CWD, 'versioned_docs', `version-${version}`), file) + ); + return subDir !== '.' ? subDir : null; +} + // return metadata for a versioned file given the file, its version (requested), // the version of the file to be used, and its language function processVersionMetadata(file, version, useVersion, language) { const metadata = extractMetadata(fs.readFileSync(file, 'utf8')).metadata; - metadata.source = 'version-' + useVersion + '/' + path.basename(file); + + // Add subdirectory information to versioned_doc metadata + // Example: `versioned_docs/version-1.1.6/projectA/readme.md` file with id `version-1.1.6-readme` + // and original_id `readme` will have metadata id of `version-1.1.6-projectA/readme` and original_id `projectA/readme` + const subDir = getSubDir(file, useVersion); + if (subDir) { + metadata.original_id = subDir + '/' + metadata.original_id; + metadata.id = metadata.id.replace( + 'version-' + useVersion + '-', + 'version-' + useVersion + '-' + subDir + '/' + ); + } + + metadata.source = + 'version-' + + useVersion + + '/' + + (subDir ? subDir + '/' + path.basename(file) : path.basename(file)); const latestVersion = versions[0]; diff --git a/lib/version.js b/lib/version.js index 1d835216b175..3473875b6dda 100755 --- a/lib/version.js +++ b/lib/version.js @@ -66,12 +66,18 @@ function makeHeader(metadata) { return header; } +function writeFileAndCreateFolder(file, content, encoding) { + mkdirp.sync(path.dirname(file)); + + fs.writeFileSync(file, content, encoding); +} + 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 + '/../' + readMetadata.getDocsPath() + '/*'); +let files = glob.sync(CWD + '/../' + readMetadata.getDocsPath() + '/**'); files.forEach(file => { const ext = path.extname(file); if (ext !== '.md' && ext !== '.markdown') { @@ -102,9 +108,18 @@ files.forEach(file => { metadata.original_id = metadata.id; metadata.id = 'version-' + version + '-' + metadata.id; - const targetFile = versionFolder + '/' + path.basename(file); + let filePath = path.basename(file); + const subDir = readMetadata.getSubDir(file); + if (subDir) { + filePath = subDir + '/' + filePath; + } + const targetFile = versionFolder + '/' + filePath; - fs.writeFileSync(targetFile, makeHeader(metadata) + rawContent, 'utf8'); + writeFileAndCreateFolder( + targetFile, + makeHeader(metadata) + rawContent, + 'utf8' + ); }); // copy sidebar if necessary From b2ddfe3aeecf67119d45b4f2362954cc60dec8fd Mon Sep 17 00:00:00 2001 From: endiliey Date: Sun, 3 Jun 2018 00:32:22 +0800 Subject: [PATCH 07/11] add windows compatibility --- lib/core/DocsLayout.js | 2 ++ lib/server/readMetadata.js | 4 +++- lib/server/versionFallback.js | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/core/DocsLayout.js b/lib/core/DocsLayout.js index 7f250f1a779f..8b9655f03b13 100644 --- a/lib/core/DocsLayout.js +++ b/lib/core/DocsLayout.js @@ -58,6 +58,7 @@ class DocsLayout extends React.Component { href={ path .relative(metadata.localized_id, metadata.previous_id) + .replace('\\', '/') .replace(/^\.\.\//, '') + '.html' }> ←{' '} @@ -78,6 +79,7 @@ class DocsLayout extends React.Component { href={ path .relative(metadata.localized_id, metadata.next_id) + .replace('\\', '/') .replace(/^\.\.\//, '') + '.html' }> {i18n diff --git a/lib/server/readMetadata.js b/lib/server/readMetadata.js index 588768040cd9..f258f428542d 100644 --- a/lib/server/readMetadata.js +++ b/lib/server/readMetadata.js @@ -124,9 +124,11 @@ function extractMetadata(content) { // Return the subdirectory path of a doc file // Example: `docs/projectA/test.md` subDir is `projectA` function getSubDir(file) { - const subDir = path.dirname( + let subDir = path.dirname( path.relative(path.join(CWD, '../', getDocsPath()), file) ); + // Convert Windows backslash paths to slash paths + subDir = subDir.replace('\\', '/'); return subDir !== '.' ? subDir : null; } diff --git a/lib/server/versionFallback.js b/lib/server/versionFallback.js index b9b5cf041d53..3a6a1bd4f98b 100644 --- a/lib/server/versionFallback.js +++ b/lib/server/versionFallback.js @@ -193,9 +193,11 @@ function diffLatestDoc(file, id) { // Return the subdirectory path of a versioned_doc file // Example: `versioned_docs/version-1.0.11/projectA/test.md` subDir is `projectA` function getSubDir(file, version) { - const subDir = path.dirname( + let subDir = path.dirname( path.relative(path.join(CWD, 'versioned_docs', `version-${version}`), file) ); + // Convert Windows backslash paths to slash paths + subDir = subDir.replace('\\', '/'); return subDir !== '.' ? subDir : null; } From c519ea51453de48511515c3ec52b2ee8cdaaee57 Mon Sep 17 00:00:00 2001 From: endiliey Date: Sun, 3 Jun 2018 19:56:13 +0800 Subject: [PATCH 08/11] refactor & remove test docs:) --- docs/projectA/README.md | 10 ----- docs/projectA/docs/architecture.md | 8 ---- docs/projectA/docs/contributors.md | 8 ---- docs/projectB/guides/install.md | 15 -------- lib/server/readMetadata.js | 60 +++++++----------------------- lib/server/utils.js | 46 +++++++++++++++++++++++ lib/server/versionFallback.js | 17 +++------ lib/write-translations.js | 3 +- website/sidebars.json | 8 ---- 9 files changed, 66 insertions(+), 109 deletions(-) delete mode 100644 docs/projectA/README.md delete mode 100644 docs/projectA/docs/architecture.md delete mode 100644 docs/projectA/docs/contributors.md delete mode 100644 docs/projectB/guides/install.md create mode 100644 lib/server/utils.js diff --git a/docs/projectA/README.md b/docs/projectA/README.md deleted file mode 100644 index b3804fea7a2f..000000000000 --- a/docs/projectA/README.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -id: readme -title: README ---- - -## Docs -Welcome to Project A, here are some available docs - -1. [Architecture](projectA/docs/architecture.md) -2. [Contributors](projectA/docs/contributors.md) diff --git a/docs/projectA/docs/architecture.md b/docs/projectA/docs/architecture.md deleted file mode 100644 index 6c606556b462..000000000000 --- a/docs/projectA/docs/architecture.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: architecture -title: Architecture ---- - -## Lorem ipsum - -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. diff --git a/docs/projectA/docs/contributors.md b/docs/projectA/docs/contributors.md deleted file mode 100644 index 85b4ccb96d7c..000000000000 --- a/docs/projectA/docs/contributors.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -id: contributors -title: Contributors ---- - -![Introducing Slash](/img/slash-introducing.png) - -But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure diff --git a/docs/projectB/guides/install.md b/docs/projectB/guides/install.md deleted file mode 100644 index 92d733590001..000000000000 --- a/docs/projectB/guides/install.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -id: install -title: Install ---- - -Project B was designed from the ground up to be easily installed and used to get your website up and running quickly. - -### Launching the server behind a proxy - -If you are behind a corporate proxy, you need to disable it for the development server requests. It can be done using the `NO_PROXY` environment variable. - -```sh -SET NO_PROXY=localhost -yarn start (or npm run start) -``` diff --git a/lib/server/readMetadata.js b/lib/server/readMetadata.js index f258f428542d..0c4e196aaa22 100644 --- a/lib/server/readMetadata.js +++ b/lib/server/readMetadata.js @@ -15,7 +15,7 @@ const chalk = require('chalk'); const env = require('./env.js'); const siteConfig = require(CWD + '/siteConfig.js'); const versionFallback = require('./versionFallback.js'); -const escapeStringRegexp = require('escape-string-regexp'); +const utils = require('./utils.js'); const SupportedHeaderFields = new Set([ 'id', @@ -121,39 +121,10 @@ function extractMetadata(content) { return {metadata, rawContent: both.content}; } -// Return the subdirectory path of a doc file -// Example: `docs/projectA/test.md` subDir is `projectA` -function getSubDir(file) { - let subDir = path.dirname( - path.relative(path.join(CWD, '../', getDocsPath()), file) - ); - // Convert Windows backslash paths to slash paths - subDir = subDir.replace('\\', '/'); - return subDir !== '.' ? subDir : null; -} - -// process the metadata for a document found in the docs folder -function processMetadata(file) { +// process the metadata for a document found in either 'docs' or 'translated_docs' +function processMetadata(file, refDir) { const result = extractMetadata(fs.readFileSync(file, 'utf8')); - - let regexSubFolder = new RegExp( - '/' + escapeStringRegexp(getDocsPath()) + '/(.*)/.*/' - ); - - const match = regexSubFolder.exec(file); - let language = 'en'; - - // Avoid misinterpreting subdirectory as language - if (match && env.translation.enabled) { - const enabledLanguages = env.translation - .enabledLanguages() - .map(language => language.tag); - - if (enabledLanguages.indexOf(match[1]) !== -1) { - language = match[1]; - } - } - + const language = utils.getLanguage(file, refDir) || 'en'; const metadata = {}; for (const fieldName of Object.keys(result.metadata)) { if (SupportedHeaderFields.has(fieldName)) { @@ -172,9 +143,11 @@ function processMetadata(file) { throw new Error('Document id cannot include "/".'); } - // If a doc file is located in a subdirectory, prepend the subdir to it's ID - // Example: `docs/projectA/test.md` with 'test' ID is changed to `projectA/test` - const subDir = getSubDir(file); + // If a file is located in a subdirectory, prepend the subdir to it's ID + // Example: + // (file: 'docusaurus/docs/projectA/test.md', ID 'test', refDir: 'docs') + // returns 'projectA/test' + const subDir = utils.getSubDir(file, refDir); if (subDir) { metadata.id = subDir + '/' + metadata.id; } @@ -250,7 +223,7 @@ function generateMetadataDocs() { const extension = path.extname(file); if (extension === '.md' || extension === '.markdown') { - const res = processMetadata(file); + const res = processMetadata(file, path.join(CWD, '../', getDocsPath())); if (!res) { return; @@ -289,23 +262,17 @@ function generateMetadataDocs() { }); // metadata for non-english docs - const regexSubFolder = /translated_docs\/(.*?)\/.*/; + const translatedDir = path.join(CWD, 'translated_docs'); files = glob.sync(CWD + '/translated_docs/**'); files.forEach(file => { - let language = 'en'; - const match = regexSubFolder.exec(file); - if (match) { - language = match[1]; - } - - if (enabledLanguages.indexOf(language) === -1) { + if (!utils.getLanguage(file, translatedDir)) { return; } const extension = path.extname(file); if (extension === '.md' || extension === '.markdown') { - const res = processMetadata(file); + const res = processMetadata(file, translatedDir); if (!res) { return; } @@ -445,7 +412,6 @@ function generateMetadataBlog() { module.exports = { getDocsPath, - getSubDir, readSidebar, extractMetadata, processMetadata, diff --git a/lib/server/utils.js b/lib/server/utils.js new file mode 100644 index 000000000000..843ca27c7568 --- /dev/null +++ b/lib/server/utils.js @@ -0,0 +1,46 @@ +/** + * 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. + */ +const path = require('path'); +const escapeStringRegexp = require('escape-string-regexp'); +const env = require('./env.js'); + +// Return the subdirectory path from a reference directory +// Example: +// (file: 'docs/projectA/test.md', refDir: 'subDir') +// returns 'projectA' +function getSubDir(file, refDir) { + let subDir = path.dirname(path.relative(refDir, file)); + subDir = subDir.replace('\\', '/'); + return subDir !== '.' ? subDir : null; +} + +// Get the corresponding enabled language locale of a file. +// Example: +// (file: '/website/translated_docs/ko/projectA/test.md', refDir: 'website/translated_docs') +// returns 'ko' +function getLanguage(file, refDir) { + let regexSubFolder = new RegExp( + '/' + escapeStringRegexp(path.basename(refDir)) + '/(.*)/.*/' + ); + const match = regexSubFolder.exec(file); + + // Avoid misinterpreting subdirectory as language + if (match && env.translation.enabled) { + const enabledLanguages = env.translation + .enabledLanguages() + .map(language => language.tag); + if (enabledLanguages.indexOf(match[1]) !== -1) { + return match[1]; + } + } + return null; +} + +module.exports = { + getSubDir, + getLanguage, +}; diff --git a/lib/server/versionFallback.js b/lib/server/versionFallback.js index 3a6a1bd4f98b..9ff867615662 100644 --- a/lib/server/versionFallback.js +++ b/lib/server/versionFallback.js @@ -12,6 +12,7 @@ const path = require('path'); const assert = require('assert'); const env = require('./env.js'); +const utils = require('./utils.js'); const siteConfig = require(CWD + '/siteConfig.js'); const ENABLE_TRANSLATION = fs.existsSync(CWD + '/languages.js'); @@ -190,17 +191,6 @@ function diffLatestDoc(file, id) { ); } -// Return the subdirectory path of a versioned_doc file -// Example: `versioned_docs/version-1.0.11/projectA/test.md` subDir is `projectA` -function getSubDir(file, version) { - let subDir = path.dirname( - path.relative(path.join(CWD, 'versioned_docs', `version-${version}`), file) - ); - // Convert Windows backslash paths to slash paths - subDir = subDir.replace('\\', '/'); - return subDir !== '.' ? subDir : null; -} - // return metadata for a versioned file given the file, its version (requested), // the version of the file to be used, and its language function processVersionMetadata(file, version, useVersion, language) { @@ -209,7 +199,10 @@ function processVersionMetadata(file, version, useVersion, language) { // Add subdirectory information to versioned_doc metadata // Example: `versioned_docs/version-1.1.6/projectA/readme.md` file with id `version-1.1.6-readme` // and original_id `readme` will have metadata id of `version-1.1.6-projectA/readme` and original_id `projectA/readme` - const subDir = getSubDir(file, useVersion); + const subDir = utils.getSubDir( + file, + path.join(CWD, 'versioned_docs', `version-${useVersion}`) + ); if (subDir) { metadata.original_id = subDir + '/' + metadata.original_id; metadata.id = metadata.id.replace( diff --git a/lib/write-translations.js b/lib/write-translations.js index 8181313df0d2..37d32a7b0f2b 100755 --- a/lib/write-translations.js +++ b/lib/write-translations.js @@ -52,7 +52,8 @@ function execute() { if (extension === '.md' || extension === '.markdown') { let res; try { - res = readMetadata.processMetadata(file); + const docsDir = path.join(CWD, '../', readMetadata.getDocsPath()); + res = readMetadata.processMetadata(file, docsDir); } catch (e) { console.error(e); process.exit(1); diff --git a/website/sidebars.json b/website/sidebars.json index b51da90e99cc..0f3f0d6ee983 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -19,14 +19,6 @@ "doc-markdown", "api-pages", "site-config" - ], - "Project A": [ - "projectA/readme", - "projectA/docs/architecture", - "projectA/docs/contributors" - ], - "Project B": [ - "projectB/guides/install" ] } } From a4aa8c7c9943fe0494b7a406f77429a86e077d89 Mon Sep 17 00:00:00 2001 From: endiliey Date: Tue, 5 Jun 2018 15:01:04 +0800 Subject: [PATCH 09/11] address code review --- lib/core/DocsLayout.js | 29 +++++++++++++++++------------ lib/server/readMetadata.js | 7 ++++--- lib/server/versionFallback.js | 14 ++++++-------- lib/version.js | 12 ++++++------ lib/write-translations.js | 2 +- 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/lib/core/DocsLayout.js b/lib/core/DocsLayout.js index 8b9655f03b13..06503c76c018 100644 --- a/lib/core/DocsLayout.js +++ b/lib/core/DocsLayout.js @@ -16,6 +16,15 @@ const path = require('path'); // component used to generate whole webpage for docs, including sidebar/header/footer class DocsLayout extends React.Component { + getRelativeURL = (from, to) => { + return ( + path + .relative(from, to) + .replace('\\', '/') + .replace(/^\.\.\//, '') + '.html' + ); + }; + render() { const metadata = this.props.metadata; const content = this.props.children; @@ -55,12 +64,10 @@ class DocsLayout extends React.Component { {metadata.previous_id && ( + href={this.getRelativeURL( + metadata.localized_id, + metadata.previous_id + )}> ←{' '} {i18n ? translation[this.props.metadata.language][ @@ -76,12 +83,10 @@ class DocsLayout extends React.Component { {metadata.next_id && ( + href={this.getRelativeURL( + metadata.localized_id, + metadata.next_id + )}> {i18n ? translation[this.props.metadata.language][ 'localized-strings' diff --git a/lib/server/readMetadata.js b/lib/server/readMetadata.js index 0c4e196aaa22..0d88afbfd7e0 100644 --- a/lib/server/readMetadata.js +++ b/lib/server/readMetadata.js @@ -149,12 +149,12 @@ function processMetadata(file, refDir) { // returns 'projectA/test' const subDir = utils.getSubDir(file, refDir); if (subDir) { - metadata.id = subDir + '/' + metadata.id; + metadata.id = `${subDir}/${metadata.id}`; } // Example: `docs/projectA/test.md` source is `projectA/test.md` metadata.source = subDir - ? subDir + '/' + path.basename(file) + ? `${subDir}/${path.basename(file)}` : path.basename(file); if (!metadata.title) { @@ -216,6 +216,7 @@ function generateMetadataDocs() { const defaultMetadatas = {}; // metadata for english files + const docsDir = path.join(CWD, '../', getDocsPath()); let files = glob.sync(CWD + '/../' + getDocsPath() + '/**'); files.forEach(file => { let language = 'en'; @@ -223,7 +224,7 @@ function generateMetadataDocs() { const extension = path.extname(file); if (extension === '.md' || extension === '.markdown') { - const res = processMetadata(file, path.join(CWD, '../', getDocsPath())); + const res = processMetadata(file, docsDir); if (!res) { return; diff --git a/lib/server/versionFallback.js b/lib/server/versionFallback.js index 9ff867615662..85c3a9394a2b 100644 --- a/lib/server/versionFallback.js +++ b/lib/server/versionFallback.js @@ -204,18 +204,16 @@ function processVersionMetadata(file, version, useVersion, language) { path.join(CWD, 'versioned_docs', `version-${useVersion}`) ); if (subDir) { - metadata.original_id = subDir + '/' + metadata.original_id; + metadata.original_id = `${subDir}/${metadata.original_id}`; metadata.id = metadata.id.replace( - 'version-' + useVersion + '-', - 'version-' + useVersion + '-' + subDir + '/' + `version-${useVersion}-`, + `version-${useVersion}-${subDir}/` ); } - metadata.source = - 'version-' + - useVersion + - '/' + - (subDir ? subDir + '/' + path.basename(file) : path.basename(file)); + metadata.source = subDir + ? `version-${useVersion}/${subDir}/${path.basename(file)}` + : `version-${useVersion}/${path.basename(file)}`; const latestVersion = versions[0]; diff --git a/lib/version.js b/lib/version.js index 3473875b6dda..0be72f6b4df2 100755 --- a/lib/version.js +++ b/lib/version.js @@ -13,6 +13,7 @@ const path = require('path'); const mkdirp = require('mkdirp'); const chalk = require('chalk'); const readMetadata = require('./server/readMetadata.js'); +const utils = require('./server/utils.js'); const versionFallback = require('./server/versionFallback.js'); const env = require('./server/env.js'); @@ -108,12 +109,11 @@ files.forEach(file => { metadata.original_id = metadata.id; metadata.id = 'version-' + version + '-' + metadata.id; - let filePath = path.basename(file); - const subDir = readMetadata.getSubDir(file); - if (subDir) { - filePath = subDir + '/' + filePath; - } - const targetFile = versionFolder + '/' + filePath; + const docsDir = path.join(CWD, '../', readMetadata.getDocsPath()); + const subDir = utils.getSubDir(file, docsDir); + const targetFile = subDir + ? `${versionFolder}/${subDir}/${path.basename(file)}` + : `${versionFolder}/${path.basename(file)}`; writeFileAndCreateFolder( targetFile, diff --git a/lib/write-translations.js b/lib/write-translations.js index 37d32a7b0f2b..4bbfc73b722a 100755 --- a/lib/write-translations.js +++ b/lib/write-translations.js @@ -46,13 +46,13 @@ function execute() { }; // look through markdown headers of docs for titles and categories to translate + const docsDir = path.join(CWD, '../', readMetadata.getDocsPath()); let files = glob.sync(CWD + '/../' + readMetadata.getDocsPath() + '/**'); files.forEach(file => { const extension = path.extname(file); if (extension === '.md' || extension === '.markdown') { let res; try { - const docsDir = path.join(CWD, '../', readMetadata.getDocsPath()); res = readMetadata.processMetadata(file, docsDir); } catch (e) { console.error(e); From 32cafe091bdf76656d2b8d765537c7fa67dbfd48 Mon Sep 17 00:00:00 2001 From: endiliey Date: Thu, 7 Jun 2018 11:49:01 +0800 Subject: [PATCH 10/11] modify crowdin.yaml to include subdir docs --- crowdin.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crowdin.yaml b/crowdin.yaml index 1ebe5fbde688..0e9df3eb53dc 100644 --- a/crowdin.yaml +++ b/crowdin.yaml @@ -5,8 +5,8 @@ preserve_hierarchy: true files: - - source: '/docs/*.md' - translation: '/website/translated_docs/%locale%/%original_file_name%' + source: '/docs/**/*.md' + translation: '/website/translated_docs/%locale%/**/%original_file_name%' languages_mapping: &anchor locale: 'af': 'af' From 2a84d978e784300a9a854f30b2f9e98975824fb7 Mon Sep 17 00:00:00 2001 From: endiliey Date: Thu, 7 Jun 2018 22:25:11 +0800 Subject: [PATCH 11/11] update crowdin yaml docs --- docs/guides-translation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides-translation.md b/docs/guides-translation.md index 3624693fd4af..d9ad2c997057 100644 --- a/docs/guides-translation.md +++ b/docs/guides-translation.md @@ -140,8 +140,8 @@ preserve_hierarchy: true files: - - source: '/docs/*.md' - translation: '/website/translated_docs/%locale%/%original_file_name%' + source: '/docs/**/*.md' + translation: '/website/translated_docs/%locale%/**/%original_file_name%' languages_mapping: &anchor locale: 'de': 'de'