Skip to content

Commit

Permalink
Refactor for dataFileSuffixes and dataFileDirBaseNameOverride con…
Browse files Browse the repository at this point in the history
…fig options #1699
  • Loading branch information
zachleat committed Dec 7, 2022
1 parent 3eb43e6 commit d0ab038
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 35 deletions.
7 changes: 6 additions & 1 deletion src/TemplateConfig.js
Expand Up @@ -192,7 +192,7 @@ class TemplateConfig {
* @param {String} pathPrefix - The new path prefix.
*/
setPathPrefix(pathPrefix) {
if(pathPrefix && pathPrefix !== '/'){
if (pathPrefix && pathPrefix !== "/") {
debug("Setting pathPrefix to %o", pathPrefix);
this.overrides.pathPrefix = pathPrefix;
}
Expand Down Expand Up @@ -227,6 +227,11 @@ class TemplateConfig {
debug("rootConfig %o", this.rootConfig);
}

/* Add additional overrides to the root config object, used for testing */
appendToRootConfig(obj) {
Object.assign(this.rootConfig, obj);
}

/*
* Process the userland plugins from the Config
*
Expand Down
110 changes: 79 additions & 31 deletions src/TemplateData.js
Expand Up @@ -170,15 +170,38 @@ class TemplateData {
return dir;
}

// This is a backwards compatibility helper with the old `jsDataFileSuffix` configuration API
getDataFileSuffixes() {
// New API
if (Array.isArray(this.config.dataFileSuffixes)) {
return this.config.dataFileSuffixes;
}
// Backwards compatibility
if (this.config.jsDataFileSuffix) {
let suffixes = [];
suffixes.push(this.config.jsDataFileSuffix); // e.g. filename.11tydata.json
suffixes.push(""); // suffix-less for free with old API, e.g. filename.json
return suffixes;
}
return []; // if both of these entries are set to false, use no files
}

// This is used exclusively for --watch and --serve chokidar targets
async getTemplateDataFileGlob() {
let dir = await this.getInputDir();
let paths = [
`${dir}/**/*.json`, // covers .11tydata.json too
`${dir}/**/*${this.config.jsDataFileSuffix}.cjs`,
`${dir}/**/*${this.config.jsDataFileSuffix}.js`,
];

let suffixes = this.getDataFileSuffixes();
for (let suffix of suffixes) {
if (suffix) {
// TODO this check is purely for backwards compat and I kinda feel like it shouldn’t be here
paths.push(`${dir}/**/*${suffix || ""}.cjs`);
paths.push(`${dir}/**/*${suffix || ""}.js`);
}
}

if (this.hasUserDataExtensions()) {
let userPaths = this.getUserDataExtensions().map(
(extension) => `${dir}/**/*.${extension}` // covers .11tydata.{extension} too
Expand All @@ -189,11 +212,22 @@ class TemplateData {
return TemplatePath.addLeadingDotSlashArray(paths);
}

// For spidering dependencies
// TODO Can we reuse getTemplateDataFileGlob instead? Maybe just filter off the .json files before scanning for dependencies
async getTemplateJavaScriptDataFileGlob() {
let dir = await this.getInputDir();
return TemplatePath.addLeadingDotSlashArray([
`${dir}/**/*${this.config.jsDataFileSuffix}.js`,
]);

let paths = [];
let suffixes = this.getDataFileSuffixes();
for (let suffix of suffixes) {
if (suffix) {
// TODO this check is purely for backwards compat and I kinda feel like it shouldn’t be here
// paths.push(`${dir}/**/*${suffix || ""}.cjs`); // Same as above
paths.push(`${dir}/**/*${suffix || ""}.js`);
}
}

return TemplatePath.addLeadingDotSlashArray(paths);
}

async getGlobalDataGlob() {
Expand Down Expand Up @@ -557,20 +591,26 @@ class TemplateData {
}
}

_addBaseToPaths(paths, base, extensions) {
let dataSuffix = this.config.jsDataFileSuffix;
_addBaseToPaths(paths, base, extensions, nonEmptySuffixesOnly = false) {
let suffixes = this.getDataFileSuffixes();

for (let suffix of suffixes) {
suffix = suffix || "";

// data suffix
paths.push(base + dataSuffix + ".js");
paths.push(base + dataSuffix + ".cjs");
paths.push(base + dataSuffix + ".json"); // default: .11tydata.json
if (nonEmptySuffixesOnly && suffix === "") {
continue;
}

// inject user extensions
this._pushExtensionsToPaths(paths, base + dataSuffix, extensions);
// data suffix
if (suffix) {
paths.push(base + suffix + ".js");
paths.push(base + suffix + ".cjs");
}
paths.push(base + suffix + ".json"); // default: .11tydata.json

// top level
paths.push(base + ".json");
this._pushExtensionsToPaths(paths, base, extensions);
// inject user extensions
this._pushExtensionsToPaths(paths, base + suffix, extensions);
}
}

async getLocalDataPaths(templatePath) {
Expand All @@ -590,13 +630,17 @@ class TemplateData {
parsed.base
);

let filePathNoExt = parsed.dir + "/" + fileNameNoExt;
let dataSuffix = this.config.jsDataFileSuffix;
// default dataSuffix: .11tydata, is appended in _addBaseToPaths
debug("Using %o to find data files.", dataSuffix);
debug(
"Using %o suffixes to find data files.",
this.getDataFileSuffixes()
);

// Template data file paths
let filePathNoExt = parsed.dir + "/" + fileNameNoExt;
this._addBaseToPaths(paths, filePathNoExt, userExtensions);

// Directory data file paths
let allDirs = TemplatePath.getAllDirs(parsed.dir);

debugDev("allDirs: %o", allDirs);
Expand All @@ -607,11 +651,13 @@ class TemplateData {
if (inputDir) {
debugDev("dirStr: %o; inputDir: %o", dir, inputDir);
}
if (!inputDir || (dir.indexOf(inputDir) === 0 && dir !== inputDir)) {
this._addBaseToPaths(paths, dirPathNoExt, userExtensions);
if (this.config.jsDataFileBase) {
let jsDataFile = dir + "/" + this.config.jsDataFileBase;
this._addBaseToPaths(paths, jsDataFile, userExtensions);
if (!inputDir || (dir.startsWith(inputDir) && dir !== inputDir)) {
if (this.config.dataFileDirBaseNameOverride) {
let indexDataFile =
dir + "/" + this.config.dataFileDirBaseNameOverride;
this._addBaseToPaths(paths, indexDataFile, userExtensions, true);
} else {
this._addBaseToPaths(paths, dirPathNoExt, userExtensions);
}
}
}
Expand All @@ -622,15 +668,17 @@ class TemplateData {
let lastInputDir = TemplatePath.addLeadingDotSlash(
TemplatePath.join(inputDir, TemplatePath.getLastPathSegment(inputDir))
);
if (lastInputDir !== "./") {

// in root input dir, search for index.11tydata.json et al
if (this.config.dataFileDirBaseNameOverride) {
let indexDataFile =
TemplatePath.getDirFromFilePath(lastInputDir) +
"/" +
this.config.dataFileDirBaseNameOverride;
this._addBaseToPaths(paths, indexDataFile, userExtensions, true);
} else if (lastInputDir !== "./") {
this._addBaseToPaths(paths, lastInputDir, userExtensions);
}
// also in root input dir, search for index.11tydata.json et al
if (this.config.jsDataFileBase) {
let jsDataFile = (TemplatePath.getDirFromFilePath(lastInputDir) +
"/" + this.config.jsDataFileBase);
this._addBaseToPaths(paths, jsDataFile, userExtensions);
}
}
}

Expand Down
11 changes: 8 additions & 3 deletions src/defaultConfig.js
Expand Up @@ -90,9 +90,14 @@ module.exports = function (config) {
htmlTemplateEngine: "liquid",
dataTemplateEngine: false, // change in 1.0
htmlOutputSuffix: "-o",
jsDataFileSuffix: ".11tydata",
jsDataFileBase: null,
// set to 'index': in every folder use datafiles 'index.11tydata.json' et al

// Renamed from `jsDataFileSuffix` in 2.0 (and swapped to an Array)
// If you remove "" we won’t look for dir/dir.json or file.json
dataFileSuffixes: [".11tydata", ""],

// "index" will look for `directory/index.*` directory data files instead of `directory/directory.*`
dataFileDirBaseNameOverride: false,

keys: {
package: "pkg",
layout: "layout",
Expand Down
25 changes: 25 additions & 0 deletions test/TemplateDataTest.js
Expand Up @@ -291,6 +291,31 @@ test("getLocalDataPaths", async (t) => {
]);
});

test("getLocalDataPaths (with dataFileDirBaseNameOverride #1699)", async (t) => {
let eleventyConfig = new TemplateConfig();
eleventyConfig.appendToRootConfig({
dataFileDirBaseNameOverride: "index",
});

let dataObj = new TemplateData("./test/stubs/", eleventyConfig);
let paths = await dataObj.getLocalDataPaths(
"./test/stubs/component/component.liquid"
);

t.deepEqual(paths, [
"./test/stubs/index.11tydata.json",
"./test/stubs/index.11tydata.cjs",
"./test/stubs/index.11tydata.js",
"./test/stubs/component/index.11tydata.json",
"./test/stubs/component/index.11tydata.cjs",
"./test/stubs/component/index.11tydata.js",
"./test/stubs/component/component.json",
"./test/stubs/component/component.11tydata.json",
"./test/stubs/component/component.11tydata.cjs",
"./test/stubs/component/component.11tydata.js",
]);
});

test("Deeper getLocalDataPaths", async (t) => {
let eleventyConfig = new TemplateConfig();
let dataObj = new TemplateData("./", eleventyConfig);
Expand Down

0 comments on commit d0ab038

Please sign in to comment.