68 lines
2.5 KiB
JavaScript
68 lines
2.5 KiB
JavaScript
// View rendering, template loading, and Handlebars registration helpers.
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const Handlebars = require('handlebars');
|
|
const { version: appVersion } = require('#root/package.json');
|
|
const { hasPermission, hasAnyPermission } = require('../rbac');
|
|
const { registerHandlebars } = require('./handlebars');
|
|
const { getMessageVariant: inferMessageVariant } = require('./public/js/toast');
|
|
|
|
const VIEWS_ROOT = path.join(__dirname, 'views');
|
|
const cache = new Map();
|
|
const SIGNAGE_VIEW_PREFIXES = new Set(['dashboard', 'clients', 'screens', 'playlists', 'slides', 'canvas-sizes', 'templates']);
|
|
|
|
registerHandlebars(Handlebars, {
|
|
viewsRoot: VIEWS_ROOT,
|
|
hasPermission: hasPermission,
|
|
hasAnyPermission: hasAnyPermission
|
|
});
|
|
|
|
function resolveTemplatePath(relativePath) {
|
|
const firstSegment = String(relativePath || '').split(/[\\/]/)[0];
|
|
if (SIGNAGE_VIEW_PREFIXES.has(firstSegment)) {
|
|
return path.join(VIEWS_ROOT, 'signage', relativePath);
|
|
}
|
|
|
|
return path.join(VIEWS_ROOT, relativePath);
|
|
}
|
|
|
|
function loadTemplate(relativePath) {
|
|
const filePath = resolveTemplatePath(relativePath);
|
|
const stat = fs.statSync(filePath);
|
|
const cached = cache.get(filePath);
|
|
if (cached && cached.mtimeMs === stat.mtimeMs) {
|
|
return cached.template;
|
|
}
|
|
const template = Handlebars.compile(fs.readFileSync(filePath, 'utf8'));
|
|
cache.set(filePath, { mtimeMs: stat.mtimeMs, template: template });
|
|
return template;
|
|
}
|
|
|
|
function renderView(viewName, context) {
|
|
const viewContext = Object.assign({ stylesheets: [], scripts: [], appVersion: appVersion }, context || {});
|
|
if (!viewContext.messageVariant) {
|
|
viewContext.messageVariant = inferMessageVariant(viewContext.message, 'primary');
|
|
}
|
|
const page = loadTemplate(`${viewName}.hbs`);
|
|
const layout = loadTemplate(path.join('shared', 'layout.hbs'));
|
|
const body = page(viewContext);
|
|
return layout(Object.assign({}, viewContext, { body: body }));
|
|
}
|
|
|
|
function renderFragment(viewName, context) {
|
|
const viewContext = Object.assign({ stylesheets: [], scripts: [], appVersion: appVersion }, context || {});
|
|
if (!viewContext.messageVariant) {
|
|
viewContext.messageVariant = inferMessageVariant(viewContext.message, 'primary');
|
|
}
|
|
const page = loadTemplate(`${viewName}.hbs`);
|
|
const layout = loadTemplate(path.join('shared', 'frame-layout.hbs'));
|
|
const body = page(viewContext);
|
|
return layout(Object.assign({}, viewContext, { body: body }));
|
|
}
|
|
|
|
module.exports = {
|
|
renderView,
|
|
renderFragment
|
|
};
|