From 844477316f131b1c414e4f64bb0b06a1edf07427 Mon Sep 17 00:00:00 2001 From: mbehzad Date: Tue, 2 Mar 2021 11:48:38 +0100 Subject: [PATCH 1/5] fix(assemble-lite, pv-stylemark): use data in layout folder only when rendering the components not pages nor component in lsg directory, re-enable assemble instance for the stylemark webpack plugin, add watch and re-build when stylemark config file changes --- packages/assemble-lite/Assemble.js | 32 ++++++++- .../webpack-plugin/getFilesToWatch.js | 68 ++++++++++++------- packages/pv-stylemark/webpack-plugin/index.js | 63 ++++++++++++----- 3 files changed, 120 insertions(+), 43 deletions(-) diff --git a/packages/assemble-lite/Assemble.js b/packages/assemble-lite/Assemble.js index 3a3181ac..d789b2c6 100644 --- a/packages/assemble-lite/Assemble.js +++ b/packages/assemble-lite/Assemble.js @@ -32,6 +32,9 @@ module.exports = class Assemble { this.lsgLayouts = {}; // data which will be used when handlebars templates are rendered this.dataPool = {}; + // data only used for the standalone components render when they are not in the lsg folder + // i.e. needed for pv-path helper + this.additionalComponentDataPool = {}; // list of current handlebar helpers (which is also the file name of these helpers). this.helpers = {}; // paths of files which throw an error during parsing or executing, @@ -71,6 +74,7 @@ module.exports = class Assemble { components, pages, data, + additionalComponentData, helpers, layouts, lsgLayouts, @@ -100,6 +104,7 @@ module.exports = class Assemble { componentPaths, pagePaths, dataPaths, + additionalComponentDataPaths, ] = await Promise.all([ getPaths(helpers), getPaths(layouts), @@ -107,6 +112,7 @@ module.exports = class Assemble { getPaths(components), getPaths(pages), getPaths(data), + getPaths(additionalComponentData), ]); this.log("Getting paths took:", timer.measure("GETTING-PATHS", true), "s"); @@ -128,6 +134,11 @@ module.exports = class Assemble { // #region remove data from memory for deleted files this._removeObsolete(this.dataPool, dataPaths, getName); + this._removeObsolete( + this.additionalComponentDataPool, + additionalComponentDataPaths, + getName + ); this._removeObsolete(this.layouts, layoutPaths, getName); this._removeObsolete(this.lsgLayouts, lsgLayoutPaths, getName); // remove obsolete helpers (strongly assuming helper name and file name are identical) @@ -151,6 +162,9 @@ module.exports = class Assemble { componentPaths = componentPaths.filter(wasModified); pagePaths = pagePaths.filter(wasModified); dataPaths = dataPaths.filter(wasModified); + additionalComponentDataPaths = additionalComponentDataPaths.filter( + wasModified + ); } timer.start("READ-AND-PARSE-FILES"); @@ -172,8 +186,15 @@ module.exports = class Assemble { // read data const readData = await this._loadData(dataPaths); + const readAdditionalComponentData = await this._loadData( + additionalComponentDataPaths + ); // merge with (potentially) old data Object.assign(this.dataPool, readData); + Object.assign( + this.additionalComponentDataPool, + readAdditionalComponentData + ); this.log( "Reading and parsing took:", @@ -432,7 +453,6 @@ module.exports = class Assemble { ...tpl.data, }; - const body = tpl.render(curData); if (tpl.layout && !this.layouts.hasOwnProperty(tpl.layout)) console.warn( `[Assemble-Lite] no layout file was defined for "${tpl.layout}"` @@ -441,8 +461,14 @@ module.exports = class Assemble { if (tpl.type === "COMPONENT") { const writingJobs = []; if (layouts.NORMAL) { + const extendedData = Object.assign( + {}, + curData, + this.additionalComponentDataPool + ); + const body = tpl.render(extendedData); const layout = this.layouts[tpl.layout] - ? this.layouts[tpl.layout].render(curData) + ? this.layouts[tpl.layout].render(extendedData) : ""; const html = layout ? layout.replace(/{%\s*body\s*%}/g, body) : body; // only write to disc when the value changes @@ -455,6 +481,7 @@ module.exports = class Assemble { } if (layouts.LSG) { + const body = tpl.render(curData); const layout = this.lsgLayouts[tpl.layout] ? this.lsgLayouts[tpl.layout].render(curData) : ""; @@ -470,6 +497,7 @@ module.exports = class Assemble { } // for PAGE else { + const body = tpl.render(curData); const layout = this.layouts[tpl.layout] ? this.layouts[tpl.layout].render(curData) : ""; diff --git a/packages/pv-stylemark/webpack-plugin/getFilesToWatch.js b/packages/pv-stylemark/webpack-plugin/getFilesToWatch.js index 90407ee1..fc4113d5 100644 --- a/packages/pv-stylemark/webpack-plugin/getFilesToWatch.js +++ b/packages/pv-stylemark/webpack-plugin/getFilesToWatch.js @@ -9,38 +9,56 @@ const { lsgIndex, lsgAssetsSrc, hbsHelperSrc, + lsgTemplatesSrc, + lsgConfigPath } = getAppConfig(); +// glob pattern for the files used in the living styleguide +const fileGlobes = { + staticStylemarkFiles: { + index: lsgIndex, + config: lsgConfigPath, + // stylemark .md files + markDown: join(componentsSrc, "**/*.md"), + // static assets / resources + resources: join(lsgAssetsSrc, "**"), + }, + assembleFiles: { + // add .json,.yaml/.yml Component data files + data: join(componentsSrc, "**/*.{json,yaml,yml}"), + // add .json,.yaml/.yml Layout data files + additionalComponentData: join(cdTemplatesSrc, "**/*.{json,yaml,yml}"), + // handlebars helpers + helpers: join(hbsHelperSrc, "*.js"), + // add .hbs Components files + components: join(componentsSrc, "**/*.hbs"), + // add .hbs Pages files + pages: join(cdPagesSrc, "**/*.hbs"), + // add .hbs Template/Layout files + layouts: join(cdTemplatesSrc, "**/*.hbs"), + // Living styleguide Layouts + lsgLayouts: join(lsgTemplatesSrc, "**/*.hbs"), + }, +}; + const getFilesToWatch = async () => { - const files = { - staticStylemarkFiles: [ - lsgIndex, - // stylemark .md files - ...(await asyncGlob(join(componentsSrc, "**/*.md"))), - // static assets / resources - ...(await asyncGlob(join(lsgAssetsSrc, "**"))), - ], + // get paths for assemble and lsg in parallel + const lsgFilesPromise = Promise.all( + Object.values(fileGlobes.staticStylemarkFiles).map(asyncGlob) + ); + const assembleFilesPromise = Promise.all( + Object.values(fileGlobes.assembleFiles).flat().map(asyncGlob) + ); + const lsgFiles = (await lsgFilesPromise).flat(); + const assembleFiles = (await assembleFilesPromise).flat(); - assembleFiles: [ - // add .json Components files - ...(await asyncGlob(join(componentsSrc, "**/*.json"))), - // add .yaml/.yml Component files - ...(await asyncGlob(join(componentsSrc, "**/*.yaml"))), - ...(await asyncGlob(join(componentsSrc, "**/*.yml"))), - // handlebars helpers - ...(await asyncGlob(join(hbsHelperSrc, "*.js"))), - // add .hbs Components files - ...(await asyncGlob(join(componentsSrc, "**/*.hbs"))), - // add .hbs Pages files - ...(await asyncGlob(join(cdPagesSrc, "**/*.hbs"))), - // add .hbs Template files - ...(await asyncGlob(join(cdTemplatesSrc, "**/*.hbs"))), - ], + return { + lsgFiles, + assembleFiles, }; - - return files; }; module.exports = { + fileGlobes, getFilesToWatch, }; diff --git a/packages/pv-stylemark/webpack-plugin/index.js b/packages/pv-stylemark/webpack-plugin/index.js index 92242fda..0a62549d 100644 --- a/packages/pv-stylemark/webpack-plugin/index.js +++ b/packages/pv-stylemark/webpack-plugin/index.js @@ -1,11 +1,17 @@ +const Assemble = require("@pro-vision/assemble-lite/Assemble"); + const buildStylemark = require("../scripts/buildStylemarkLsg"); -const { getFilesToWatch } = require("./getFilesToWatch"); +const { getFilesToWatch, fileGlobes } = require("./getFilesToWatch"); +const { resolveApp, getAppConfig, join } = require("../helper/paths"); + +const { destPath, componentsSrc } = getAppConfig(); class PvStylemarkPlugin { constructor() { // list of files currently being watched which need a re-compile of assemble or stylemark when modified - this.watchedFiles = { staticStylemarkFiles: [], assembleFiles: [] }; + this.watchedFiles = { lsgFiles: [], assembleFiles: [] }; // is false during watch mode and when re-compiling because some files have been changed this.firstRun = true; + this.assemble = new Assemble(); } apply(compiler) { compiler.hooks.emit.tapAsync( @@ -13,10 +19,7 @@ class PvStylemarkPlugin { async (compilation, callback) => { // add files for stylemark and assemble to webpack to watch const filesToWatch = await getFilesToWatch(); - const allFiles = Object.values(filesToWatch).reduce( - (acc, val) => acc.concat(val), - [] - ); + const allFiles = Object.values(filesToWatch).flat(); allFiles.forEach((file) => compilation.fileDependencies.add(file)); const changedFiles = this.firstRun @@ -25,14 +28,11 @@ class PvStylemarkPlugin { const changedStylemarkFiles = changedFiles // modified / removed files - .filter((filePath) => - this.watchedFiles.staticStylemarkFiles.includes(filePath) - ) + .filter((filePath) => this.watchedFiles.lsgFiles.includes(filePath)) // new files .concat( - filesToWatch.staticStylemarkFiles.filter( - (filePath) => - !this.watchedFiles.staticStylemarkFiles.includes(filePath) + filesToWatch.lsgFiles.filter( + (filePath) => !this.watchedFiles.lsgFiles.includes(filePath) ) ); const changedAssembleFiles = changedFiles @@ -54,11 +54,42 @@ class PvStylemarkPlugin { const buildAssemble = this.firstRun || changedAssembleFiles.length; const copyStylemarkFiles = this.firstRun || changedStylemarkFiles.length; + // only needs build on the first run and when stylemark or assemble files have been changed + const buildLsg = buildAssemble || copyStylemarkFiles; + + if (buildAssemble) { + await this.assemble.build( + { + baseDir: resolveApp(componentsSrc), + components: resolveApp(fileGlobes.assembleFiles.components), + pages: resolveApp(fileGlobes.assembleFiles.pages), + data: resolveApp(fileGlobes.assembleFiles.data), + additionalComponentData: resolveApp( + fileGlobes.assembleFiles.additionalComponentData + ), + helpers: resolveApp(fileGlobes.assembleFiles.helpers), + layouts: resolveApp(fileGlobes.assembleFiles.layouts), + lsgLayouts: resolveApp(fileGlobes.assembleFiles.lsgLayouts), + componentsTargetDirectory: resolveApp( + join(destPath, "components") + ), + pagesTargetDirectory: resolveApp(join(destPath, "pages")), + lsgComponentsTargetDirectory: resolveApp( + join(destPath, "/lsg_components") + ), + }, + this.firstRun ? null : changedAssembleFiles + ); + } - await buildStylemark({ - shouldCopyStyleguideFiles: copyStylemarkFiles, - shouldAssemble: buildAssemble, - }); + if (buildLsg) { + await buildStylemark({ + // unless files were changed but none was a static stylemark file + shouldCopyStyleguideFiles: copyStylemarkFiles, + // unless files were changed but none was an assemble file + shouldAssemble: false, + }); + } // for the next iteration this.firstRun = false; From 70a506c8583680433decc7b9f86ac0c4087af2f5 Mon Sep 17 00:00:00 2001 From: mbehzad Date: Tue, 2 Mar 2021 18:12:28 +0100 Subject: [PATCH 2/5] style: lint --- packages/pv-stylemark/webpack-plugin/getFilesToWatch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pv-stylemark/webpack-plugin/getFilesToWatch.js b/packages/pv-stylemark/webpack-plugin/getFilesToWatch.js index fc4113d5..f3c15a17 100644 --- a/packages/pv-stylemark/webpack-plugin/getFilesToWatch.js +++ b/packages/pv-stylemark/webpack-plugin/getFilesToWatch.js @@ -10,7 +10,7 @@ const { lsgAssetsSrc, hbsHelperSrc, lsgTemplatesSrc, - lsgConfigPath + lsgConfigPath, } = getAppConfig(); // glob pattern for the files used in the living styleguide From 4f07739536a0f01bbb0f60797576f383add5beeb Mon Sep 17 00:00:00 2001 From: mbehzad Date: Thu, 25 Nov 2021 09:17:43 +0100 Subject: [PATCH 3/5] refactor(assemble-lite): update usage of ja-yaml after its version was updated in pkg --- packages/assemble-lite/Assemble.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/assemble-lite/Assemble.js b/packages/assemble-lite/Assemble.js index d789b2c6..191787d4 100644 --- a/packages/assemble-lite/Assemble.js +++ b/packages/assemble-lite/Assemble.js @@ -3,7 +3,7 @@ const { readJson, readFile } = require("fs-extra"); const pvHandlebars = require("handlebars").create(); const { loadFront } = require("yaml-front-matter"); const handlebarsHelpers = require("handlebars-helpers/lib/index"); -const { safeLoad } = require("js-yaml"); +const { load } = require("js-yaml"); const Timer = require("./Timer"); const Visitor = require("./Visitor"); @@ -559,7 +559,7 @@ module.exports = class Assemble { if (ext === ".json") { dataPool[filename] = await readJson(path); } else if (ext === ".yaml" || ext === ".yml") { - dataPool[filename] = safeLoad(await readFile(path, "utf-8"), { + dataPool[filename] = load(await readFile(path, "utf-8"), { filename, }); } From d7e850d26c5432535ecdfd2fafe179969f128b4d Mon Sep 17 00:00:00 2001 From: mbehzad Date: Tue, 22 Nov 2022 11:16:44 +0100 Subject: [PATCH 4/5] feat(assemble-lite): improve intergartion of error messages in webpack update paths, fix hlf missing operator, remove duplicate build invocations --- packages/assemble-lite/Assemble.js | 42 +++++++++++++------ .../assembleClickdummyComponents.js | 2 - .../assembleClickdummyPages.js | 2 - .../lsg_tasks/assembleLSGComponents.js | 2 - .../pv-stylemark/scripts/buildStylemarkLsg.js | 2 +- packages/pv-stylemark/scripts/dev.js | 6 +-- packages/pv-stylemark/scripts/prod.js | 6 +-- packages/pv-stylemark/webpack-plugin/index.js | 3 ++ 8 files changed, 39 insertions(+), 26 deletions(-) diff --git a/packages/assemble-lite/Assemble.js b/packages/assemble-lite/Assemble.js index 191787d4..06907a24 100644 --- a/packages/assemble-lite/Assemble.js +++ b/packages/assemble-lite/Assemble.js @@ -49,6 +49,20 @@ module.exports = class Assemble { if (this.verbose) console.log("[Assemble-Lite] ", ...args); } + // first error message during build, will be used to throw when there was no custom onError handler and the build should hard fail + _errorMsg = null; + // call the optional provided callback function with the error message + error(msg, error) { + console.error(msg); + console.error(error); + + const errorMsg = `${msg} :: ${error.message}`; + + if (this.onError) this.onError?.(errorMsg); + // there is no custom error handler, throw and fail the build + else if (!this._errorMsg) this._errorMsg = errorMsg; + } + /** * builds all the html pages, based on the provided arguments, * an re-uses cached items from the previous builds @@ -64,6 +78,7 @@ module.exports = class Assemble { * componentsTargetDirectory, * pagesTargetDirectory, * lsgComponentsTargetDirectory, + * onError?, * } * @param {string[] | null} modifiedFiles - list of paths of files which have been modified compared to the last build * @memberof Assemble @@ -81,11 +96,14 @@ module.exports = class Assemble { componentsTargetDirectory, pagesTargetDirectory, lsgComponentsTargetDirectory, + onError, }, modifiedFiles ) { this.log("--------------------------------"); this.log("Build start ..."); + this.onError = onError; + this._errorMsg = null; // use a timer to measure execution duration for individual tasks const timer = new Timer(); @@ -329,6 +347,8 @@ module.exports = class Assemble { ); this.log("Build end. took:", timer.measure("BUILD", true), "s"); this.log("--------------------------------"); + + if (this._errorMsg) throw this._errorMsg; } /** @@ -530,10 +550,10 @@ module.exports = class Assemble { pvHandlebars.registerHelper(helperFn); this.helpers[getName(path)] = { path, name: getName(path) }; } catch (error) { - console.error( - `[Assemble-Lite] Failed reading handlebars helper ${basename(path)}` + this.error( + `[Assemble-Lite] Failed reading handlebars helper ${basename(path)}`, + error ); - console.error(error); // make sure on the next iteration, the helper is re-read, // so the user can't forget about this issue this.failedPaths.push(path); @@ -564,10 +584,10 @@ module.exports = class Assemble { }); } } catch (error) { - console.error( - `[assemble-lite] Failed reading data file ${basename(path)}` + this.error( + `[assemble-lite] Failed reading data file ${basename(path)}`, + error ); - console.error(error); // make sure on the next iteration, the helper is re-read, // so the user can't forget about this issue (if it still exist) this.failedPaths.push(path); @@ -601,8 +621,7 @@ module.exports = class Assemble { path )}`; const errorMarkup = ``; - console.error(errorMessage); - console.error(error); + this.error(errorMessage, error); return { clearedMarkup: errorMarkup, @@ -626,11 +645,9 @@ module.exports = class Assemble { failed: false, }; } catch (error) { - console.error(); const errorMessage = `[assemble-lite] error parsing ${filename}.hbs`; const errorMarkup = ``; - console.error(errorMessage); - console.error(error); + this.error(errorMessage, error); return { ast: pvHandlebars.parse(errorMarkup), @@ -659,8 +676,7 @@ module.exports = class Assemble { const errorMessage = `[assemble-lite] failed to render template for ${basename( path )}`; - console.error(errorMessage); - console.error(error); + this.error(errorMessage, error); return ``; } diff --git a/packages/pv-stylemark/gulp-tasks/clickdummy_tasks/assembleClickdummyComponents.js b/packages/pv-stylemark/gulp-tasks/clickdummy_tasks/assembleClickdummyComponents.js index e25f90fa..3ee19db5 100644 --- a/packages/pv-stylemark/gulp-tasks/clickdummy_tasks/assembleClickdummyComponents.js +++ b/packages/pv-stylemark/gulp-tasks/clickdummy_tasks/assembleClickdummyComponents.js @@ -28,8 +28,6 @@ const assembleClickdummyComponents = () => { }); }; -assembleClickdummyComponents(); - module.exports = { assembleClickdummyComponents, }; diff --git a/packages/pv-stylemark/gulp-tasks/clickdummy_tasks/assembleClickdummyPages.js b/packages/pv-stylemark/gulp-tasks/clickdummy_tasks/assembleClickdummyPages.js index 204d8d40..f1c000b9 100644 --- a/packages/pv-stylemark/gulp-tasks/clickdummy_tasks/assembleClickdummyPages.js +++ b/packages/pv-stylemark/gulp-tasks/clickdummy_tasks/assembleClickdummyPages.js @@ -26,8 +26,6 @@ const assembleClickdummyPages = () => { }); }; -assembleClickdummyPages(); - module.exports = { assembleClickdummyPages, }; diff --git a/packages/pv-stylemark/gulp-tasks/lsg_tasks/assembleLSGComponents.js b/packages/pv-stylemark/gulp-tasks/lsg_tasks/assembleLSGComponents.js index b1549a14..820f3732 100644 --- a/packages/pv-stylemark/gulp-tasks/lsg_tasks/assembleLSGComponents.js +++ b/packages/pv-stylemark/gulp-tasks/lsg_tasks/assembleLSGComponents.js @@ -25,8 +25,6 @@ const assembleLSGComponents = () => { }); }; -assembleLSGComponents(); - module.exports = { assembleLSGComponents, }; diff --git a/packages/pv-stylemark/scripts/buildStylemarkLsg.js b/packages/pv-stylemark/scripts/buildStylemarkLsg.js index 3fd39635..d980605d 100644 --- a/packages/pv-stylemark/scripts/buildStylemarkLsg.js +++ b/packages/pv-stylemark/scripts/buildStylemarkLsg.js @@ -25,7 +25,7 @@ async function buildStylemarkLsg({ shouldCopyStyleguideFiles && new Promise((resolve) => copyClickdummyFiles(resolve)), shouldAssemble && assembleClickdummyComponents(), - shouldAssemble & assembleClickdummyPages(), + shouldAssemble && assembleClickdummyPages(), shouldAssemble && assembleLSGComponents(), ]); diff --git a/packages/pv-stylemark/scripts/dev.js b/packages/pv-stylemark/scripts/dev.js index de7c874b..e747528e 100644 --- a/packages/pv-stylemark/scripts/dev.js +++ b/packages/pv-stylemark/scripts/dev.js @@ -3,17 +3,17 @@ const gulp = require("gulp"); // Assemble Clickdummy const { assembleClickdummyComponents, -} = require("../gulp-tasks/assembleWrapper/assembleClickdummyComponents"); +} = require("../gulp-tasks/clickdummy_tasks/assembleClickdummyComponents"); const { assembleClickdummyPages, -} = require("../gulp-tasks/assembleWrapper/assembleClickdummyPages"); +} = require("../gulp-tasks/clickdummy_tasks/assembleClickdummyPages"); const { copyClickdummyFiles, } = require("../gulp-tasks/clickdummy_tasks/copyClickdummyFiles"); // Assemble Stylemark const { assembleLSGComponents, -} = require("../gulp-tasks/assembleWrapper/assembleLSGComponents"); +} = require("../gulp-tasks/lsg_tasks/assembleLSGComponents"); const { copyStyleguideFiles, } = require("../gulp-tasks/lsg_tasks/copyStyleguideFiles"); diff --git a/packages/pv-stylemark/scripts/prod.js b/packages/pv-stylemark/scripts/prod.js index 97e5ca70..ab74f1e2 100644 --- a/packages/pv-stylemark/scripts/prod.js +++ b/packages/pv-stylemark/scripts/prod.js @@ -3,17 +3,17 @@ const gulp = require("gulp"); // Assemble Clickdummy const { assembleClickdummyComponents, -} = require("../gulp-tasks/assembleWrapper/assembleClickdummyComponents"); +} = require("../gulp-tasks/clickdummy_tasks/assembleClickdummyComponents"); const { assembleClickdummyPages, -} = require("../gulp-tasks/assembleWrapper/assembleClickdummyPages"); +} = require("../gulp-tasks/clickdummy_tasks/assembleClickdummyPages"); const { copyClickdummyFiles, } = require("../gulp-tasks/clickdummy_tasks/copyClickdummyFiles"); // Assemble Stylemark const { assembleLSGComponents, -} = require("../gulp-tasks/assembleWrapper/assembleLSGComponents"); +} = require("../gulp-tasks/lsg_tasks/assembleLSGComponents"); const { copyStyleguideFiles, } = require("../gulp-tasks/lsg_tasks/copyStyleguideFiles"); diff --git a/packages/pv-stylemark/webpack-plugin/index.js b/packages/pv-stylemark/webpack-plugin/index.js index 0a62549d..df928825 100644 --- a/packages/pv-stylemark/webpack-plugin/index.js +++ b/packages/pv-stylemark/webpack-plugin/index.js @@ -77,6 +77,9 @@ class PvStylemarkPlugin { lsgComponentsTargetDirectory: resolveApp( join(destPath, "/lsg_components") ), + onError(errorMessage) { + compilation.errors.push(errorMessage); + }, }, this.firstRun ? null : changedAssembleFiles ); From 8546c3c917f5bad1c15a9a97d53b6a1178536e5a Mon Sep 17 00:00:00 2001 From: mbehzad Date: Tue, 27 Dec 2022 10:16:36 +0100 Subject: [PATCH 5/5] fix(assemble-lite): take into account for layout having helpers which process template output --- packages/assemble-lite/Assemble.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/packages/assemble-lite/Assemble.js b/packages/assemble-lite/Assemble.js index 06907a24..aa3de261 100644 --- a/packages/assemble-lite/Assemble.js +++ b/packages/assemble-lite/Assemble.js @@ -435,7 +435,9 @@ module.exports = class Assemble { */ async _processLayout(path, type) { const filename = basename(path, ".hbs"); - const markup = await asyncReadFile(path); + let markup = await asyncReadFile(path); + // replace {%body%} with a handlebars interpolation, which will be replaced with the content of rendered template + markup = markup.replace(/{%\s*body\s*%}/g, "{{{__body__}}}"); const { ast, partials, pathExpressions, failed } = this._analyseHandlebars( markup, path @@ -487,10 +489,9 @@ module.exports = class Assemble { this.additionalComponentDataPool ); const body = tpl.render(extendedData); - const layout = this.layouts[tpl.layout] - ? this.layouts[tpl.layout].render(extendedData) - : ""; - const html = layout ? layout.replace(/{%\s*body\s*%}/g, body) : body; + const html = this.layouts[tpl.layout] + ? this.layouts[tpl.layout].render({ ...extendedData, __body__: body }) + : body; // only write to disc when the value changes if (html !== tpl.output.NORMAL) writingJobs.push( @@ -502,10 +503,9 @@ module.exports = class Assemble { if (layouts.LSG) { const body = tpl.render(curData); - const layout = this.lsgLayouts[tpl.layout] - ? this.lsgLayouts[tpl.layout].render(curData) - : ""; - const html = layout ? layout.replace(/{%\s*body\s*%}/g, body) : body; + const html = this.lsgLayouts[tpl.layout] + ? this.lsgLayouts[tpl.layout].render({ ...curData, __body__: body }) + : body; if (html !== tpl.output.LSG) writingJobs.push( asyncWriteFile(lsgComponentsTargetDirectory, reldir, filename, html) @@ -518,10 +518,9 @@ module.exports = class Assemble { // for PAGE else { const body = tpl.render(curData); - const layout = this.layouts[tpl.layout] - ? this.layouts[tpl.layout].render(curData) - : ""; - const html = layout ? layout.replace(/{%\s*body\s*%}/g, body) : body; + const html = this.layouts[tpl.layout] + ? this.layouts[tpl.layout].render({ ...curData, __body__: body }) + : body; if (html !== tpl.output.NORMAL) await asyncWriteFile(pagesTargetDirectory, reldir, filename, html); tpl.output.NORMAL = html;