Skip to content

Commit

Permalink
Get a layout chain from a template. Work preparing for the incrementa…
Browse files Browse the repository at this point in the history
…l data graph. Also fixes #915.
  • Loading branch information
zachleat committed Feb 16, 2020
1 parent 5f57ce0 commit 0bd6576
Show file tree
Hide file tree
Showing 17 changed files with 165 additions and 88 deletions.
2 changes: 1 addition & 1 deletion src/Eleventy.js
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ Arguments:
*
* @private
* @method
* @param {String} path - Watch this file.
* @param {String} path - File that triggered a re-run (added or modified)
*/
async _watch(path) {
if (path) {
Expand Down
52 changes: 29 additions & 23 deletions src/Template.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,26 @@ class Template extends TemplateContent {
return TemplatePath.stripLeadingSubPath(this.parsed.dir, this.inputDir);
}

getLayout(layoutKey) {
if(!this._layout || layoutKey !== this._layoutKey) {
this._layoutKey = layoutKey;
this._layout = TemplateLayout.getTemplate(
layoutKey,
this.getInputDir(),
this.config
);
}
return this._layout;
}

async getLayoutChain() {
if(!this._layout) {
await this.getData();
}

return this._layout.getLayoutChain();
}

get baseFile() {
return (this._extensionMap || EleventyExtensionMap).removeTemplateExtension(
this.parsed.base
Expand Down Expand Up @@ -189,11 +209,7 @@ class Template extends TemplateContent {
async _testGetAllLayoutFrontMatterData() {
let frontMatterData = await this.getFrontMatterData();
if (frontMatterData[this.config.keys.layout]) {
let layout = TemplateLayout.getTemplate(
frontMatterData[this.config.keys.layout],
this.getInputDir(),
this.config
);
let layout = this.getLayout(frontMatterData[this.config.keys.layout]);
return await layout.getData();
}
return {};
Expand All @@ -210,17 +226,14 @@ class Template extends TemplateContent {
}

let frontMatterData = await this.getFrontMatterData();
let foundLayout =
let layoutKey =
frontMatterData[this.config.keys.layout] ||
localData[this.config.keys.layout];

let mergedLayoutData = {};
if (foundLayout) {
let layout = TemplateLayout.getTemplate(
foundLayout,
this.getInputDir(),
this.config
);
if (layoutKey) {
let layout = this.getLayout(layoutKey);

mergedLayoutData = await layout.getData();
debugDev(
"%o getData() get merged layout chain front matter",
Expand All @@ -231,8 +244,8 @@ class Template extends TemplateContent {
let mergedData = TemplateData.mergeDeep(
this.config,
{},
mergedLayoutData,
localData,
mergedLayoutData,
frontMatterData
);
mergedData = await this.addPageDate(mergedData);
Expand Down Expand Up @@ -319,11 +332,7 @@ class Template extends TemplateContent {

async renderLayout(tmpl, tmplData) {
let layoutKey = tmplData[tmpl.config.keys.layout];
let layout = TemplateLayout.getTemplate(
layoutKey,
this.getInputDir(),
this.config
);
let layout = this.getLayout(layoutKey);
debug("%o is using layout %o", this.inputPath, layoutKey);

// TODO reuse templateContent from templateMap
Expand Down Expand Up @@ -529,11 +538,8 @@ class Template extends TemplateContent {
let content;
let layoutKey = mapEntry.data[this.config.keys.layout];
if (layoutKey) {
let layout = TemplateLayout.getTemplate(
layoutKey,
this.getInputDir(),
this.config
);
let layout = this.getLayout(layoutKey);

content = await layout.render(page.data, page.templateContent);
} else {
content = page.templateContent;
Expand Down
16 changes: 9 additions & 7 deletions src/TemplateData.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,21 +205,23 @@ class TemplateData {
let dataFileConflicts = {};

for (let j = 0, k = files.length; j < k; j++) {
let folders = await this.getObjectPathForDataFile(files[j]);
let objectPathTarget = await this.getObjectPathForDataFile(files[j]);
let data = await this.getDataValue(files[j], rawImports);

if (dataFileConflicts[folders]) {
// if two global files have the same path (but different extensions)
// and conflict, let’s merge them.
if (dataFileConflicts[objectPathTarget]) {
debugWarn(
`merging global data from ${files[j]} with an already existing global data file (${dataFileConflicts[folders]}). Overriding existing keys`
`merging global data from ${files[j]} with an already existing global data file (${dataFileConflicts[objectPathTarget]}). Overriding existing keys.`
);

let oldData = lodashget(globalData, folders);
let oldData = lodashget(globalData, objectPathTarget);
data = TemplateData.mergeDeep(this.config, oldData, data);
}

dataFileConflicts[folders] = files[j];
debug(`Found global data file ${files[j]} and adding as: ${folders}`);
lodashset(globalData, folders, data);
dataFileConflicts[objectPathTarget] = files[j];
debug(`Found global data file ${files[j]} and adding as: ${objectPathTarget}`);
lodashset(globalData, objectPathTarget, data);
}

return globalData;
Expand Down
12 changes: 11 additions & 1 deletion src/TemplateLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const TemplatePath = require("./TemplatePath");

const templateCache = require("./TemplateCache");
const config = require("./Config");
const debug = require("debug")("Eleventy:TemplateLayout");
// const debug = require("debug")("Eleventy:TemplateLayout");
const debugDev = require("debug")("Dev:Eleventy:TemplateLayout");

class TemplateLayout extends TemplateContent {
Expand Down Expand Up @@ -81,18 +81,28 @@ class TemplateLayout extends TemplateContent {

let map = await this.getTemplateLayoutMap();
let dataToMerge = [];
let layoutChain = [];
for (let j = map.length - 1; j >= 0; j--) {
layoutChain.push(map[j].template.inputPath);
dataToMerge.push(map[j].frontMatterData);
}

// Deep merge of layout front matter
let data = TemplateData.mergeDeep(this.config, {}, ...dataToMerge);
delete data[this.config.keys.layout];

this.layoutChain = layoutChain.reverse();
this.dataCache = data;
return data;
}

async getLayoutChain() {
if(!this.layoutChain) {
await this.getData();
}
return this.layoutChain;
}

async getCompiledLayoutFunctions() {
if (this.compileCache) {
return this.compileCache;
Expand Down
4 changes: 2 additions & 2 deletions src/TemplateLayoutPathResolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ class TemplateLayoutPathResolver {
fs.existsSync(this.pathAlreadyHasExtension)
) {
this.filename = this.path;
this.fullPath = this.pathAlreadyHasExtension;
this.fullPath = TemplatePath.addLeadingDotSlash(this.pathAlreadyHasExtension);
} else {
this.filename = this.findFileName();
this.fullPath = this.dir + "/" + this.filename;
this.fullPath = TemplatePath.addLeadingDotSlash(this.dir + "/" + this.filename);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/TemplateMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ ${permalinks[page.url]
}
}

async getCollectionsData() {
async _testGetCollectionsData() {
if (!this.cached) {
await this.cache();
}
Expand Down
6 changes: 3 additions & 3 deletions src/TemplateWriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ class TemplateWriter {
debug("Found: %o", paths);

let passthroughManager = this.getFileManager().getPassthroughManager();
passthroughManager.setIncrementalFile(
this.incrementalFile ? this.incrementalFile : false
);
if(this.incrementalFile) {
passthroughManager.setIncrementalFile(this.incrementalFile);
}

promises.push(
passthroughManager.copyAll(paths).catch(e => {
Expand Down
25 changes: 22 additions & 3 deletions test/TemplateLayoutTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,47 @@ import TemplateLayout from "../src/TemplateLayout";
test("Creation", t => {
t.is(
new TemplateLayout("base", "./test/stubs").getInputPath(),
"test/stubs/_includes/base.njk"
"./test/stubs/_includes/base.njk"
);

t.throws(() => {
new TemplateLayout("doesnotexist", "./test/stubs").getInputPath();
});
});

test("Get Layout Chain", async t => {
let tl = new TemplateLayout("layouts/layout-inherit-a.njk", "./test/stubs");

t.deepEqual(await tl.getLayoutChain(), [
"./test/stubs/_includes/layouts/layout-inherit-a.njk",
"./test/stubs/_includes/layouts/layout-inherit-b.njk",
"./test/stubs/_includes/layouts/layout-inherit-c.njk"
]);
});

test("Get Front Matter Data", async t => {
let tl = new TemplateLayout("layouts/layout-inherit-a.njk", "./test/stubs");
t.is(tl.getInputPath(), "test/stubs/_includes/layouts/layout-inherit-a.njk");
t.is(tl.getInputPath(), "./test/stubs/_includes/layouts/layout-inherit-a.njk");

t.deepEqual(await tl.getData(), {
let data = await tl.getData();

t.deepEqual(data, {
inherits: "a",
secondinherits: "b",
thirdinherits: "c"
});
t.deepEqual(await tl.getLayoutChain(), [
"./test/stubs/_includes/layouts/layout-inherit-a.njk",
"./test/stubs/_includes/layouts/layout-inherit-b.njk",
"./test/stubs/_includes/layouts/layout-inherit-c.njk"
]);

t.deepEqual(await tl.getData(), {
inherits: "a",
secondinherits: "b",
thirdinherits: "c"
});

});

test("Augment data with layoutContent", async t => {
Expand Down
Loading

0 comments on commit 0bd6576

Please sign in to comment.