Files
Mastering-Node.js-Web-Devel…/Chapter 10/End of Chapter/part2app/src/server/custom_engine.ts
T
2024-05-29 18:54:49 +01:00

45 lines
1.4 KiB
TypeScript

import { readFile } from "fs";
import { Express } from "express";
import * as features from "./custom_features";
const renderTemplate = (path: string, context: any,
callback: (err: any, response: string | undefined) => void) => {
readFile(path, (err, data) => {
if (err != undefined) {
callback("Cannot generate content", undefined);
} else {
callback(undefined, parseTemplate(data.toString(),
{ ...context, features }));
}
});
};
const parseTemplate = (template: string, context: any) => {
const ctx = Object.keys(context)
.map((k) => `const ${k} = context.${k}`)
.join(";");
const expr = /{{(.*)}}/gm;
return template.toString().replaceAll(expr, (match, group) => {
const evalFunc= (expr: string) => {
return eval(`${ctx};${expr}`)
}
try {
if (group.trim()[0] === "@") {
group = `features.${group.trim().substring(1)}`;
group = group.replace(/\)$/m, ", context, evalFunc)");
}
let result = evalFunc(group);
if (expr.test(result)) {
result = parseTemplate(result, context);
}
return result;
} catch (err: any) {
return err;
}
});
}
export const registerCustomTemplateEngine = (expressApp: Express) =>
expressApp.engine("custom", renderTemplate);