87 lines
3.0 KiB
TypeScript
87 lines
3.0 KiB
TypeScript
import nunjucks, {Environment} from "nunjucks";
|
|
import config from "config";
|
|
import {Express, NextFunction, Request, Response, Router} from "express";
|
|
import ApplicationComponent from "../ApplicationComponent";
|
|
import Controller, {RouteParams} from "../Controller";
|
|
import * as querystring from "querystring";
|
|
import {ParsedUrlQueryInput} from "querystring";
|
|
import * as util from "util";
|
|
import * as path from "path";
|
|
import Middleware from "../Middleware";
|
|
|
|
export default class NunjucksComponent extends ApplicationComponent {
|
|
private readonly viewsPath: string[];
|
|
private environment?: Environment;
|
|
|
|
public constructor(viewsPath: string[] = ['views']) {
|
|
super();
|
|
this.viewsPath = viewsPath;
|
|
}
|
|
|
|
public async start(app: Express): Promise<void> {
|
|
const opts = {
|
|
autoescape: true,
|
|
noCache: !config.get('view.cache'),
|
|
throwOnUndefined: true,
|
|
};
|
|
this.environment = new nunjucks.Environment([
|
|
...this.viewsPath.map(path => new nunjucks.FileSystemLoader(path, opts)),
|
|
new nunjucks.FileSystemLoader(path.join(__dirname, '../../../views'), opts),
|
|
new nunjucks.FileSystemLoader(path.join(__dirname, '../views'), opts),
|
|
], opts)
|
|
.addGlobal('route', (
|
|
route: string,
|
|
params: RouteParams = [],
|
|
query: ParsedUrlQueryInput = {},
|
|
absolute: boolean = false,
|
|
): string => {
|
|
return Controller.route(route, params, query, absolute);
|
|
})
|
|
.addGlobal('app_version', this.getApp().getVersion())
|
|
.addGlobal('core_version', this.getApp().getCoreVersion())
|
|
.addGlobal('querystring', querystring)
|
|
.addGlobal('app', config.get('app'))
|
|
|
|
.addFilter('dump', (val) => {
|
|
return util.inspect(val);
|
|
})
|
|
.addFilter('hex', (v: number) => {
|
|
return v.toString(16);
|
|
});
|
|
|
|
app.engine('njk', (path, options, callback) => {
|
|
this.environment?.render(path, options, (err, res) => {
|
|
callback(err, res || undefined);
|
|
});
|
|
});
|
|
}
|
|
|
|
public async init(_router: Router): Promise<void> {
|
|
this.use(NunjucksMiddleware);
|
|
}
|
|
|
|
public getEnvironment(): Environment {
|
|
if (!this.environment) throw new Error('Environment not initialized.');
|
|
return this.environment;
|
|
}
|
|
}
|
|
|
|
export class NunjucksMiddleware extends Middleware {
|
|
private env?: Environment;
|
|
|
|
protected async handle(req: Request, res: Response, next: NextFunction): Promise<void> {
|
|
this.env = this.app.as(NunjucksComponent).getEnvironment();
|
|
res.locals.url = req.url;
|
|
res.locals.params = req.params;
|
|
res.locals.query = req.query;
|
|
res.locals.body = req.body;
|
|
|
|
next();
|
|
}
|
|
|
|
public getEnvironment(): Environment {
|
|
if (!this.env) throw new Error('Environment not initialized.');
|
|
return this.env;
|
|
}
|
|
}
|