diff --git a/examples/docSidebar.js b/examples/docSidebar.js new file mode 100644 index 0000000000..9c96494a00 --- /dev/null +++ b/examples/docSidebar.js @@ -0,0 +1,10 @@ +module.exports = { + docs: { + Docusaurus: ["doc1"], + "First Category": ["doc2"], + "Second Category": ["doc3"] + }, + "docs-other": { + "First Category": ["doc4", "doc5"] + } +}; diff --git a/lib/core/DocsSidebar.js b/lib/core/DocsSidebar.js index 3a58f01b37..1402ee9bb9 100644 --- a/lib/core/DocsSidebar.js +++ b/lib/core/DocsSidebar.js @@ -15,8 +15,8 @@ const siteConfig = require(process.cwd() + "/siteConfig.js"); class DocsSidebar extends React.Component { render() { - let layout = this.props.metadata.layout; - let docsCategories = require("./" + layout + "Categories.js"); + let sidebar = this.props.metadata.sidebar; + let docsCategories = require("./" + sidebar + "Categories.js"); return ( { + const extension = path.extname(file); + if (extension === ".md" || extension === ".markdown") { + const metadata = extractMetadata(fs.readFileSync(file, "utf8")).metadata; + if (!metadata.id) { + return; + } + const data = {}; + data["category"] = metadata.category; + data["sidebar"] = metadata.layout; + if (metadata.next) { + data["next"] = metadata.next; + } + if (metadata.previous) { + data["previous"] = metadata.previous; + } + docs[metadata.id] = data; + } +}); + +Object.keys(docs).forEach(id => { + if (!docs[id].previous) { + sidebar[docs[id].sidebar] = {}; + sidebar[docs[id].sidebar][docs[id].category] = []; + sidebar[docs[id].sidebar][docs[id].category].push(id); + } +}); + +Object.keys(sidebar).forEach(sb => { + const categories = sidebar[sb]; + Object.keys(categories).forEach(category => { + const docIds = categories[category]; + next = docIds[0]; + while (next) { + id = next; + next = docs[id].next; + if (!next) { + return; + } + if (docs[next].category === category) { + docIds.push(next); + } else { + categories[docs[next].category] = []; + categories[docs[next].category].push(next); + } + } + }); +}); + +const str = prettier.format("module.exports = " + JSON.stringify(sidebar)); +fs.writeFileSync(process.cwd() + "/docSidebar.js", str, "utf8"); diff --git a/lib/server/generate.js b/lib/server/generate.js index f91ac75ae3..43517cfc09 100644 --- a/lib/server/generate.js +++ b/lib/server/generate.js @@ -87,12 +87,12 @@ function execute() { } const readCategories = require("./readCategories.js"); - let layouts = {}; + let sidebars = {}; for (let i = 0; i < Metadata.length; i++) { - let layout = Metadata[i].layout; - if (layouts[layout] !== true) { - layouts[layout] = true; - readCategories(layout); + let sidebar = Metadata[i].sidebar; + if (sidebars[sidebar] !== true) { + sidebars[sidebar] = true; + readCategories(sidebar); } } diff --git a/lib/server/readCategories.js b/lib/server/readCategories.js index bc56da7518..23a5427ee2 100644 --- a/lib/server/readCategories.js +++ b/lib/server/readCategories.js @@ -23,7 +23,7 @@ if (fs.existsSync(CWD + "/languages.js")) { } ]; } -function readCategories(layout) { +function readCategories(sidebar) { const enabledLanguages = []; languages.filter(lang => lang.enabled).map(lang => { enabledLanguages.push(lang.tag); @@ -35,7 +35,7 @@ function readCategories(layout) { const language = enabledLanguages[k]; const metadatas = Metadata.filter(metadata => { - return metadata.layout === layout && metadata.language === language; + return metadata.sidebar === sidebar && metadata.language === language; }); // Build a hashmap of article_id -> metadata @@ -91,7 +91,7 @@ function readCategories(layout) { } fs.writeFileSync( - __dirname + "/../core/" + layout + "Categories.js", + __dirname + "/../core/" + sidebar + "Categories.js", "/**\n" + " * @generated\n" + " */\n" + diff --git a/lib/server/readMetadata.js b/lib/server/readMetadata.js index 521f267624..9398f40609 100644 --- a/lib/server/readMetadata.js +++ b/lib/server/readMetadata.js @@ -12,6 +12,8 @@ const CWD = process.cwd(); const path = require("path"); const fs = require("fs"); const os = require("os"); +const sidebar = require(CWD + "/docSidebar.js"); +const glob = require("glob"); let languages; if (fs.existsSync(CWD + "/languages.js")) { languages = require(CWD + "/languages.js"); @@ -24,7 +26,37 @@ if (fs.existsSync(CWD + "/languages.js")) { } ]; } -const glob = require("glob"); + +function readSidebar(allSidebars) { + const order = {}; + + Object.keys(allSidebars).forEach(sidebar => { + const categories = allSidebars[sidebar]; + + let ids = []; + let categoryOrder = []; + Object.keys(categories).forEach(category => { + ids = ids.concat(categories[category]); + for (let i = 0; i < categories[category].length; i++) { + categoryOrder.push(category); + } + }); + + for (let i = 0; i < ids.length; i++) { + const id = ids[i]; + let previous, next; + if (i > 0) previous = ids[i - 1]; + if (i < ids.length - 1) next = ids[i + 1]; + order[id] = { + previous: previous, + next: next, + sidebar: sidebar, + category: categoryOrder[i] + }; + } + }); + return order; +} function splitHeader(content) { const lines = content.split(os.EOL); @@ -84,20 +116,29 @@ function processMetadata(file) { // change ids previous, next metadata.localized_id = metadata.id; metadata.id = language + "-" + metadata.id; - if (metadata.previous) { - metadata.previous_id = metadata.previous; - metadata.previous = language + "-" + metadata.previous; - } - if (metadata.next) { - metadata.next_id = metadata.next; - metadata.next = language + "-" + metadata.next; - } metadata.language = language; + const order = readSidebar(sidebar); + const id = metadata.localized_id; + + metadata.sidebar = order[id].sidebar; + metadata.category = order[id].category; + + if (order[id].next) { + metadata.next_id = order[id].next; + metadata.next = language + "-" + order[id].next; + } + if (order[id].previous) { + metadata.previous_id = order[id].previous; + metadata.previous = language + "-" + order[id].previous; + } + return { metadata, rawContent: rawContent }; } function generateDocsMetadata() { + const order = readSidebar(sidebar); + const regexSubFolder = /docs\/(.*)\/.*/; const enabledLanguages = []; @@ -126,7 +167,7 @@ function generateDocsMetadata() { if (!res) { return; } - const metadata = res.metadata; + let metadata = res.metadata; metadatas.push(metadata); } }); @@ -181,7 +222,9 @@ function generateBlogMetadata() { ); } -module.exports.extractMetadata = extractMetadata; -module.exports.processMetadata = processMetadata; -module.exports.generateDocsMetadata = generateDocsMetadata; -module.exports.generateBlogMetadata = generateBlogMetadata; +module.exports = { + extractMetadata, + processMetadata, + generateDocsMetadata, + generateBlogMetadata +}; diff --git a/lib/server/server.js b/lib/server/server.js index 510e8cbc3d..c3974af4fc 100644 --- a/lib/server/server.js +++ b/lib/server/server.js @@ -17,7 +17,6 @@ function execute(port) { const fs = require("fs-extra"); const os = require("os"); const path = require("path"); - const readMetadata = require("./readMetadata.js"); const toSlug = require("../core/toSlug.js"); const mkdirp = require("mkdirp"); const glob = require("glob"); @@ -70,22 +69,25 @@ function execute(port) { /****************************************************************************/ + let readMetadata; let Metadata; let readCategories; function reloadMetadataCategories() { + purgeCache("./readMetadata.js"); + readMetadata = require("./readMetadata.js"); readMetadata.generateDocsMetadata(); purgeCache("../core/metadata.js"); Metadata = require("../core/metadata.js"); purgeCache("./readCategories.js"); readCategories = require("./readCategories.js"); - let layouts = {}; + let sidebars = {}; for (let i = 0; i < Metadata.length; i++) { - let layout = Metadata[i].layout; - if (layouts[layout] !== true) { - layouts[layout] = true; - readCategories(layout); + let sidebar = Metadata[i].sidebar; + if (sidebars[sidebar] !== true) { + sidebars[sidebar] = true; + readCategories(sidebar); } } } diff --git a/lib/write-translations.js b/lib/write-translations.js index 4bd7e711a1..610850e557 100644 --- a/lib/write-translations.js +++ b/lib/write-translations.js @@ -41,11 +41,13 @@ function execute() { files.forEach(file => { const extension = path.extname(file); if (extension === ".md" || extension === ".markdown") { - const metadata = readMetadata.extractMetadata( - fs.readFileSync(file, "utf8") - ).metadata; + const res = readMetadata.processMetadata(file); + if (!res) { + return + } + const metadata = res.metadata; - translations["localized-strings"][metadata.id] = metadata.title; + translations["localized-strings"][metadata.localized_id] = metadata.title; translations["localized-strings"][metadata.category] = metadata.category; if (metadata.sidebar_title) { diff --git a/package.json b/package.json index 79b0bcbb04..aa921b5db8 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "express": "^4.15.3", "fs-extra": "^3.0.1", "glob": "^7.1.2", + "prettier": "^1.5.3", "react": "^15.5.4", "react-dom": "^15.5.4", "request": "^2.81.0", @@ -27,6 +28,7 @@ "docusaurus-build": "./lib/build-files.js", "docusaurus-publish": "./lib/publish-gh-pages.js", "docusaurus-examples": "./lib/copy-examples.js", - "docusaurus-write-translations": "./lib/write-translations.js" + "docusaurus-write-translations": "./lib/write-translations.js", + "docusaurus-gen-doc-sidebar": "./lib/gen-doc-sidebar.js" } }