From 3bb1d1ee4020a57f146b57cf3ec11c513e918854 Mon Sep 17 00:00:00 2001 From: Chng-Zhi-Xuan Date: Wed, 25 Jul 2018 10:35:35 +0800 Subject: [PATCH 1/6] Site: Initialise head folder --- lib/Site.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/Site.js b/lib/Site.js index fcb692078c..39c8af9074 100644 --- a/lib/Site.js +++ b/lib/Site.js @@ -35,6 +35,7 @@ const FAVICON_DEFAULT_PATH = 'favicon.ico'; const FONT_AWESOME_PATH = 'asset/font-awesome.csv'; const FOOTER_PATH = '_markbind/footers/footer.md'; const GLYPHICONS_PATH = 'asset/glyphicons.csv'; +const HEAD_FOLDER_PATH = '_markbind/head'; const INDEX_MARKDOWN_FILE = 'index.md'; const PAGE_TEMPLATE_NAME = 'page.ejs'; const SITE_CONFIG_NAME = 'site.json'; @@ -170,6 +171,7 @@ Site.initSite = function (rootPath) { const boilerplatePath = path.join(rootPath, BOILERPLATE_FOLDER_NAME); const configPath = path.join(rootPath, SITE_CONFIG_NAME); const footerPath = path.join(rootPath, FOOTER_PATH); + const headFolderPath = path.join(rootPath, HEAD_FOLDER_PATH); const indexPath = path.join(rootPath, INDEX_MARKDOWN_FILE); const siteNavPath = path.join(rootPath, SITE_NAV_PATH); const userDefinedVariablesPath = path.join(rootPath, USER_VARIABLES_PATH); @@ -210,6 +212,13 @@ Site.initSite = function (rootPath) { } return fs.outputFileAsync(footerPath, FOOTER_DEFAULT); }) + .then(() => fs.accessAsync(headFolderPath)) + .catch(() => { + if (fs.existsSync(headFolderPath)) { + return Promise.resolve(); + } + return fs.mkdirSync(headFolderPath); + }) .then(() => fs.accessAsync(siteNavPath)) .catch(() => { if (fs.existsSync(siteNavPath)) { From e99721e6c8c39d2cb8ea72dc0b77f0806f36aa5e Mon Sep 17 00:00:00 2001 From: Chng-Zhi-Xuan Date: Wed, 25 Jul 2018 10:36:07 +0800 Subject: [PATCH 2/6] Page: Read and process specified head file --- lib/Page.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/Page.js b/lib/Page.js index 4fa88a5850..cea043d091 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -13,6 +13,7 @@ const MarkBind = require('./markbind/lib/parser'); const md = require('./markbind/lib/markdown-it'); const FOOTERS_FOLDER_PATH = '_markbind/footers'; +const HEAD_FOLDER_PATH = '_markbind/head'; const NAVIGATION_FOLDER_PATH = '_markbind/navigation'; const FLEX_BODY_DIV_ID = 'flex-body'; @@ -59,9 +60,10 @@ function Page(pageConfig) { this.resultPath = pageConfig.resultPath; this.frontMatter = {}; + this.headFileReferences = ''; this.headings = {}; - this.includedFiles = {}; this.headingIndexingLevel = pageConfig.headingIndexingLevel; + this.includedFiles = {}; } /** @@ -160,6 +162,7 @@ Page.prototype.prepareTemplateData = function () { baseUrl: this.baseUrl, content: this.content, faviconUrl: this.faviconUrl, + headFileReferences: this.headFileReferences, title: prefixedTitle, }; }; @@ -293,6 +296,22 @@ Page.prototype.insertSiteNav = function (pageData) { + ''; }; +Page.prototype.collectHeadFiles = function () { + const { head } = this.frontMatter; + if (!head) { + return; + } + const headFilePath = path.join(this.rootPath, HEAD_FOLDER_PATH, head); + const headFileContent = fs.readFileSync(headFilePath, 'utf8'); + // Set head file as an includedFile + this.includedFiles[headFilePath] = true; + // Map variables + const newBaseUrl = calculateNewBaseUrl(this.sourcePath, this.rootPath, this.baseUrlMap) || ''; + const userDefinedVariables = this.userDefinedVariablesMap[path.join(this.rootPath, newBaseUrl)]; + const headFileMappedData = nunjucks.renderString(headFileContent, userDefinedVariables); + this.headFileReferences = headFileMappedData.trim(); +}; + Page.prototype.generate = function (builtFiles) { this.includedFiles = {}; this.includedFiles[this.sourcePath] = true; @@ -325,6 +344,8 @@ Page.prototype.generate = function (builtFiles) { const baseUrl = newBaseUrl ? `${this.baseUrl}/${newBaseUrl}` : this.baseUrl; const hostBaseUrl = this.baseUrl; + this.collectHeadFiles(); + this.headFileReferences = nunjucks.renderString(this.headFileReferences, { baseUrl, hostBaseUrl }); this.content = nunjucks.renderString(this.content, { baseUrl, hostBaseUrl }); return fs.outputFileAsync(this.resultPath, this.template(this.prepareTemplateData())); }) From 0b3bf04ac11041d9db4e2029163e616269ddbbc3 Mon Sep 17 00:00:00 2001 From: Chng-Zhi-Xuan Date: Wed, 25 Jul 2018 10:36:41 +0800 Subject: [PATCH 3/6] Template: Add head file reference --- lib/template/page.ejs | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/template/page.ejs b/lib/template/page.ejs index 94303732e2..b0a835096f 100644 --- a/lib/template/page.ejs +++ b/lib/template/page.ejs @@ -12,6 +12,7 @@ + <%- headFileReferences %> <% if (faviconUrl) { %><% } %> From 7d2fa1daad016d7655d1e886d933725a2ec3a0b8 Mon Sep 17 00:00:00 2001 From: Chng-Zhi-Xuan Date: Wed, 25 Jul 2018 10:37:02 +0800 Subject: [PATCH 4/6] Test: Update Site unit tests --- test/unit/Site.test.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/unit/Site.test.js b/test/unit/Site.test.js index 5cebdbcd40..1ce375345e 100644 --- a/test/unit/Site.test.js +++ b/test/unit/Site.test.js @@ -75,7 +75,7 @@ test('Site Init in existing directory generates correct assets', async () => { await Site.initSite(''); const paths = Object.keys(fs.vol.toJSON()); const originalNumFiles = Object.keys(json).length; - const expectedNumBuilt = 6; + const expectedNumBuilt = 7; expect(paths.length).toEqual(originalNumFiles + expectedNumBuilt); // _boilerplates @@ -84,6 +84,9 @@ test('Site Init in existing directory generates correct assets', async () => { // footer.md expect(fs.readFileSync(path.resolve('_markbind/footers/footer.md'), 'utf8')).toEqual(FOOTER_MD_DEFAULT); + // head folder + expect(fs.existsSync(path.resolve('_markbind/head'), 'utf8')).toEqual(true); + // site-nav.md expect(fs.readFileSync(path.resolve('_markbind/navigation/site-nav.md'), 'utf8')) .toEqual(SITE_NAV_MD_DEFAULT); @@ -107,7 +110,7 @@ test('Site Init in directory which does not exist generates correct assets', asy await Site.initSite('newDir'); const paths = Object.keys(fs.vol.toJSON()); const originalNumFiles = Object.keys(json).length; - const expectedNumBuilt = 6; + const expectedNumBuilt = 7; expect(paths.length).toEqual(originalNumFiles + expectedNumBuilt); @@ -117,6 +120,9 @@ test('Site Init in directory which does not exist generates correct assets', asy expect(fs.readFileSync(path.resolve('newDir/_markbind/footers/footer.md'), 'utf8')) .toEqual(FOOTER_MD_DEFAULT); + // head folder + expect(fs.existsSync(path.resolve('newDir/_markbind/head'), 'utf8')).toEqual(true); + // site-nav.md expect(fs.readFileSync(path.resolve('newDir/_markbind/navigation/site-nav.md'), 'utf8')) .toEqual(SITE_NAV_MD_DEFAULT); From 16f7f65d2e259cdd293f4ed40036830546d678d9 Mon Sep 17 00:00:00 2001 From: Chng-Zhi-Xuan Date: Wed, 25 Jul 2018 10:37:42 +0800 Subject: [PATCH 5/6] Test: Update test_site to insert head file --- test/test_site/_markbind/head/myCustomHead.md | 1 + test/test_site/expected/bugs/index.html | 1 + test/test_site/expected/headFiles/customScript.js | 2 ++ test/test_site/expected/index.html | 1 + test/test_site/expected/siteData.json | 1 + test/test_site/expected/sub_site/index.html | 1 + test/test_site/headFiles/customScript.js | 2 ++ test/test_site/index.md | 1 + 8 files changed, 10 insertions(+) create mode 100644 test/test_site/_markbind/head/myCustomHead.md create mode 100644 test/test_site/expected/headFiles/customScript.js create mode 100644 test/test_site/headFiles/customScript.js diff --git a/test/test_site/_markbind/head/myCustomHead.md b/test/test_site/_markbind/head/myCustomHead.md new file mode 100644 index 0000000000..5498678d98 --- /dev/null +++ b/test/test_site/_markbind/head/myCustomHead.md @@ -0,0 +1 @@ + diff --git a/test/test_site/expected/bugs/index.html b/test/test_site/expected/bugs/index.html index 19e282c000..04fc2c76b1 100644 --- a/test/test_site/expected/bugs/index.html +++ b/test/test_site/expected/bugs/index.html @@ -12,6 +12,7 @@ + diff --git a/test/test_site/expected/headFiles/customScript.js b/test/test_site/expected/headFiles/customScript.js new file mode 100644 index 0000000000..e1bf352ca2 --- /dev/null +++ b/test/test_site/expected/headFiles/customScript.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line no-console +console.info('custom script inserted into head successfully!'); diff --git a/test/test_site/expected/index.html b/test/test_site/expected/index.html index f5bbaf028e..e473651616 100644 --- a/test/test_site/expected/index.html +++ b/test/test_site/expected/index.html @@ -12,6 +12,7 @@ + diff --git a/test/test_site/expected/siteData.json b/test/test_site/expected/siteData.json index 2db9085edb..26783d954a 100644 --- a/test/test_site/expected/siteData.json +++ b/test/test_site/expected/siteData.json @@ -21,6 +21,7 @@ "title": "Hello World", "footer": "footer.md", "siteNav": "site-nav.md", + "head": "myCustomHead.md", "src": "index.md" }, { diff --git a/test/test_site/expected/sub_site/index.html b/test/test_site/expected/sub_site/index.html index 3b2530797b..69a6d24088 100644 --- a/test/test_site/expected/sub_site/index.html +++ b/test/test_site/expected/sub_site/index.html @@ -12,6 +12,7 @@ + diff --git a/test/test_site/headFiles/customScript.js b/test/test_site/headFiles/customScript.js new file mode 100644 index 0000000000..e1bf352ca2 --- /dev/null +++ b/test/test_site/headFiles/customScript.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line no-console +console.info('custom script inserted into head successfully!'); diff --git a/test/test_site/index.md b/test/test_site/index.md index ce4634c9d1..0d876c3517 100644 --- a/test/test_site/index.md +++ b/test/test_site/index.md @@ -2,6 +2,7 @@ title: Hello World footer: footer.md siteNav: site-nav.md +head: myCustomHead.md From 7c7600fddf584212eaa8c6f303e739ce961f5e4f Mon Sep 17 00:00:00 2001 From: Chng-Zhi-Xuan Date: Wed, 25 Jul 2018 10:38:08 +0800 Subject: [PATCH 6/6] Docs: Add page head content insertion section --- docs/userGuide/contentAuthoring.md | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/docs/userGuide/contentAuthoring.md b/docs/userGuide/contentAuthoring.md index f14439e9c3..aa37622590 100644 --- a/docs/userGuide/contentAuthoring.md +++ b/docs/userGuide/contentAuthoring.md @@ -375,6 +375,50 @@ Front matter can also be included from a separate file, just like how content ca This will result in `index.md` having the title `Binary Search Tree` and the specified keywords in order for it to be looked up through the search bar. +### Inserting content into a page's head element + +While authoring your website, you may want to have your own CSS or Javascript files to be included in a page. + +- Start by creating a head file with Markdown extension (`.md`) in the `_markbind/head` folder. + - More than one head file can be created for different pages. + +- Author your `