sc-site-sync/lib/common/adminHtml.js
2026-10-19 01:25:16 -05:00

46 lines
1.7 KiB
JavaScript

// Small HTML pieces of the plugin's server-rendered admin pages.
const { escapeHtml } = require("./htmlEscape");
// The hidden CSRF input for a form POST (Saltcorn's csurf token).
const csrfField = (req) => {
const token = req.csrfToken ? req.csrfToken() : "";
return `<input type="hidden" name="_csrf" value="${escapeHtml(token)}">`;
};
// Bootstrap nav-pills (links = [[href, label], ...]) with the current page marked
// active. The active link is the one whose href is the LONGEST boundary-safe
// prefix of the request path, so a sub-page still highlights its parent tab.
const navPills = (req, links) => {
const cur = String((req && (req.originalUrl || req.path)) || "").split("?")[0].replace(/\/+$/, "");
let activeHref = "";
for (const [href] of links) {
const h = href.replace(/\/+$/, "");
if ((cur === h || cur.startsWith(h + "/")) && h.length > activeHref.length) {
activeHref = h;
}
}
const items = links.map(([href, label]) => {
const on = href.replace(/\/+$/, "") === activeHref;
return ` <li class="nav-item"><a class="nav-link${on ? " active" : ""}"${on ? ' aria-current="page"' : ""} href="${escapeHtml(href)}">${escapeHtml(label)}</a></li>`;
}).join("\n");
return `<ul class="nav nav-pills mb-3">\n${items}\n</ul>`;
};
// Flash a message and redirect (Post/Redirect/Get). Saltcorn renders flash text
// as raw HTML and messages can echo admin input, so it is escaped here; nothing
// is reflected from the query string.
const flashRedirect = (req, res, url, type, message) => {
req.flash(type, escapeHtml(message));
res.redirect(url);
};
module.exports = {
csrfField,
navPills,
flashRedirect
};