epiphany/node_modules/@11ty/eleventy/src/TemplateEngineManager.js

148 lines
5.1 KiB
JavaScript
Raw Normal View History

2023-12-09 22:19:03 -08:00
const EleventyBaseError = require("./EleventyBaseError");
class TemplateEngineManagerConfigError extends EleventyBaseError {}
class TemplateEngineManager {
constructor(eleventyConfig) {
if (!eleventyConfig) {
throw new TemplateEngineManagerConfigError("Missing `config` argument.");
}
this.eleventyConfig = eleventyConfig;
this.engineCache = {};
}
get config() {
return this.eleventyConfig.getConfig();
}
static isCustomEngineSimpleAlias(entry) {
let keys = Object.keys(entry);
if (keys.length > 2) {
return false;
}
return !keys.some((key) => {
return key !== "key" && key !== "extension";
});
}
get keyToClassNameMap() {
if (!this._keyToClassNameMap) {
this._keyToClassNameMap = {
ejs: "Ejs",
md: "Markdown",
html: "Html",
hbs: "Handlebars",
mustache: "Mustache",
haml: "Haml",
pug: "Pug",
njk: "Nunjucks",
liquid: "Liquid",
"11ty.js": "JavaScript",
};
// Custom entries *can* overwrite default entries above
if ("extensionMap" in this.config) {
for (let entry of this.config.extensionMap) {
// either the key does not already exist or it is not a simple alias and is an override: https://www.11ty.dev/docs/languages/custom/#overriding-an-existing-template-language
if (
!this._keyToClassNameMap[entry.key] ||
!TemplateEngineManager.isCustomEngineSimpleAlias(entry)
) {
// throw an error if you try to override a Custom engine, this is a short term error until we swap this to use the extension instead of the key to get the class
if (this._keyToClassNameMap[entry.key] === "Custom") {
throw new Error(
`An attempt was made to override the *already* overridden "${entry.key}" template syntax via the \`addExtension\` configuration API. A maximum of one override is currently supported. If youre trying to add an alias to an existing syntax, make sure only the \`key\` property is present in the addExtension options object.`
);
}
this._keyToClassNameMap[entry.key] = "Custom";
}
}
}
}
return this._keyToClassNameMap;
}
reset() {
this.engineCache = {};
}
getClassNameFromTemplateKey(key) {
let keys = this.keyToClassNameMap;
return keys[key];
}
hasEngine(name) {
return !!this.getClassNameFromTemplateKey(name);
}
getEngineClassByExtension(extension) {
// We include these as raw strings (and not more readable variables) so theyre parsed by the serverless bundler.
if (extension === "ejs") {
return require("./Engines/Ejs");
} else if (extension === "md") {
return require("./Engines/Markdown");
} else if (extension === "html") {
return require("./Engines/Html");
} else if (extension === "hbs") {
return require("./Engines/Handlebars");
} else if (extension === "mustache") {
return require("./Engines/Mustache");
} else if (extension === "haml") {
return require("./Engines/Haml");
} else if (extension === "pug") {
return require("./Engines/Pug");
} else if (extension === "njk") {
return require("./Engines/Nunjucks");
} else if (extension === "liquid") {
return require("./Engines/Liquid");
} else if (extension === "11ty.js") {
return require("./Engines/JavaScript");
} else {
return require("./Engines/Custom");
}
}
getEngine(name, dirs, extensionMap) {
if (!this.hasEngine(name)) {
throw new Error(`Template Engine ${name} does not exist in getEngine (dirs: ${dirs})`);
}
// TODO these cached engines should be based on extensions not name, then we can remove the error in
// "Double override (not aliases) throws an error" test in TemplateRenderCustomTest.js
if (this.engineCache[name]) {
return this.engineCache[name];
}
let cls = this.getEngineClassByExtension(name);
let instance = new cls(name, dirs, this.eleventyConfig);
instance.extensionMap = extensionMap;
instance.engineManager = this;
// If provided a "Custom" engine using addExtension,
// But that engine's instance is *not* custom,
// The user must be overriding an existing engine
// i.e. addExtension('md', { ...overrideBehavior })
if (
this.getClassNameFromTemplateKey(name) === "Custom" &&
instance.constructor.name !== "CustomEngine"
) {
const CustomEngine = this.getEngineClassByExtension();
const overrideCustomEngine = new CustomEngine(name, dirs, this.eleventyConfig);
// Keep track of the "default" engine 11ty would normally use
// This allows the user to access the default engine in their override
overrideCustomEngine.setDefaultEngine(instance);
instance = overrideCustomEngine;
}
// Make sure cache key is based on name and not path
// Custom class is used for all plugins, cache once per plugin
this.engineCache[name] = instance;
return instance;
}
}
module.exports = TemplateEngineManager;