tatianamac 6d5445ecc5 update
2019-11-26 14:50:43 -08:00

207 lines
5.3 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 TemplatePath = require("./TemplatePath");
const TemplateEngine = require("./Engines/TemplateEngine");
const EleventyBaseError = require("./EleventyBaseError");
const EleventyExtensionMap = require("./EleventyExtensionMap");
const config = require("./Config");
// const debug = require("debug")("Eleventy:TemplateRender");
class TemplateRenderUnknownEngineError extends EleventyBaseError {}
// works with full path names or short engine name
class TemplateRender {
constructor(tmplPath, inputDir, extensionMap) {
if (!tmplPath) {
throw new Error(
`TemplateRender requires a tmplPath argument, instead of ${tmplPath}`
);
}
this.path = tmplPath;
this.extensionMap = extensionMap;
// optional
this.includesDir = this._normalizeIncludesDir(inputDir);
this.parseMarkdownWith = this.config.markdownTemplateEngine;
this.parseHtmlWith = this.config.htmlTemplateEngine;
this.init(tmplPath);
this.useMarkdown = this.engineName === "md";
}
get config() {
if (!this._config) {
this._config = config.getConfig();
}
return this._config;
}
set config(config) {
this._config = config;
if (this.engine) {
this.engine.config = config;
}
}
init(engineNameOrPath) {
this.engineName = this.cleanupEngineName(engineNameOrPath);
if (!this.engineName) {
throw new TemplateRenderUnknownEngineError(
`Unknown engine for ${engineNameOrPath}`
);
}
this.engine = TemplateEngine.getEngine(this.engineName, this.includesDir);
this.engine.initRequireCache(this.path);
}
cleanupEngineName(tmplPath) {
return TemplateRender._cleanupEngineName(
tmplPath,
this.extensionMap || EleventyExtensionMap
);
}
static cleanupEngineName(tmplPath) {
return TemplateRender._cleanupEngineName(tmplPath, EleventyExtensionMap);
}
static _cleanupEngineName(tmplPath, extensionMapRef) {
return extensionMapRef.getKey(tmplPath);
}
static hasEngine(tmplPath) {
let name = TemplateRender.cleanupEngineName(tmplPath);
return TemplateEngine.hasEngine(name);
}
static parseEngineOverrides(engineName) {
let overlappingEngineWarningCount = 0;
let engines = [];
let uniqueLookup = {};
let usingMarkdown = false;
(engineName || "")
.split(",")
.map(name => {
return name.toLowerCase().trim();
})
.forEach(name => {
// html is assumed (treated as plaintext by the system)
if (!name || name === "html") {
return;
}
if (name === "md") {
usingMarkdown = true;
return;
}
if (!uniqueLookup[name]) {
engines.push(name);
uniqueLookup[name] = true;
// we already short circuit md and html types above
overlappingEngineWarningCount++;
}
});
if (overlappingEngineWarningCount > 1) {
throw new Error(
`Dont mix multiple templating engines in your front matter overrides (exceptions for HTML and Markdown). You used: ${engineName}`
);
}
// markdown should always be first
if (usingMarkdown) {
// todo use unshift or something (no wifi here to look up docs :D)
engines = ["md"].concat(engines);
}
return engines;
}
// used for error logging.
getEnginesStr() {
if (this.engineName === "md" && this.useMarkdown) {
return this.parseMarkdownWith + " (and markdown)";
}
return this.engineName;
}
setEngineOverride(engineName, bypassMarkdown) {
let engines = TemplateRender.parseEngineOverrides(engineName);
// when overriding, Template Engines with HTML will instead use the Template Engine as primary and output HTML
// So any HTML engine usage here will never use a preprocessor templating engine.
this.setHtmlEngine(false);
if (!engines.length) {
this.init("html");
return;
}
this.init(engines[0]);
let usingMarkdown = engines[0] === "md" && !bypassMarkdown;
this.setUseMarkdown(usingMarkdown);
if (usingMarkdown) {
// false means only parse markdown and not with a preprocessor template engine
this.setMarkdownEngine(engines.length > 1 ? engines[1] : false);
}
}
getEngineName() {
return this.engineName;
}
getIncludesDir() {
return this.includesDir;
}
_normalizeIncludesDir(dir) {
return TemplatePath.join(
dir ? dir : this.config.dir.input,
this.config.dir.includes
);
}
isEngine(engine) {
return this.engineName === engine;
}
setUseMarkdown(useMarkdown) {
this.useMarkdown = !!useMarkdown;
}
setMarkdownEngine(markdownEngine) {
this.parseMarkdownWith = markdownEngine;
}
setHtmlEngine(htmlEngineName) {
this.parseHtmlWith = htmlEngineName;
}
async render(str, data) {
return this.engine.render(str, data);
}
async getCompiledTemplate(str) {
// TODO refactor better, move into TemplateEngine logic
if (this.engineName === "md") {
return this.engine.compile(
str,
this.path,
this.parseMarkdownWith,
!this.useMarkdown
);
} else if (this.engineName === "html") {
return this.engine.compile(str, this.path, this.parseHtmlWith);
} else {
return this.engine.compile(str, this.path);
}
}
}
module.exports = TemplateRender;