Files
pulse-signage/src/web/view.js
T
2026-08-01 21:41:44 +01:00

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
};