epiphany/node_modules/@11ty/eleventy/src/TemplateEngineManager.js
2023-12-09 22:19:03 -08:00

147 lines
5.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;