viewson
Version:
This package is a view engine which supports JSON and BSON data
84 lines (67 loc) • 2.23 kB
JavaScript
// Copyright © 2025 Aarav Garg
// Licensed under the BSD 3-Clause License
function attributes(a) {
if (!Array.isArray(a)) return '';
let ans = '';
a.forEach(attribute => {
let key = Object.keys(attribute)[0];
let value = attribute[key];
ans += `${key}="${value}" `;
});
return ans.trim();
}
function compile(data, dynData = {}, start = true) {
let html = '';
if (start) {
html += `<!DOCTYPE html>
<html>
<head>
`;
// Render head
for (let key in data.html5.head) {
let value = data.html5.head[key];
const dynKey = value?.content?.dynamic || value?.dynamic;
if (dynKey) value = dynData[dynKey];
html += renderTag(key, value, dynData);
}
html += `</head>
<body>
`;
// Render body
for (let key in data.html5.body) {
let value = data.html5.body[key];
const dynKey = value?.content?.dynamic || value?.dynamic;
if (dynKey) value = dynData[dynKey];
html += renderTag(key, value, dynData);
}
html += `</body>
</html>`;
} else {
// Recursive nested content
for (let key in data) {
let value = data[key];
const dynKey = value?.content?.dynamic || value?.dynamic;
if (dynKey) value = dynData[dynKey];
html += renderTag(key, value, dynData);
}
}
return html;
}
function renderTag(tag, value, dynData = []) {
let inner = '';
let attrs = '';
// Determine inner content
if (typeof (value?.content ?? value) === 'string') {
inner = value?.content ?? value;
} else if (typeof value?.content === 'object') {
inner = compile(value.content, dynData, false); // Recursive
} else if (typeof value === 'object') {
inner = compile(value, dynData, false); // Directly render
}
// Safely get attributes
if (typeof value === 'object' && value.attributes) {
attrs = attributes(value.attributes);
}
return `<${tag} ${attrs}>${inner}</${tag}>\n`;
}
module.exports = compile;