eureka-web/lib/template.js

63 lines
2.3 KiB
JavaScript
Raw Normal View History

/**
* template.js — общая оболочка сайта Эврики.
*
* Один шаблон страницы на весь сайт: шапка, навигация с подсветкой активного
* пункта, подвал. Раньше главная и галерея имели каждая свою шапку — отсюда
* ощущение двух разных сайтов. Теперь шапка и подвал описаны здесь один раз.
*
* Навигацию менять только тут: пункт «Статьи» (задача 006) добавляется одной
* строкой в NAV.
*/
export function esc(s) {
return String(s)
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
}
// Порядок и состав пунктов навигации. href — корневые (работают с любой глубины).
export const NAV = [
{ key: "home", label: "Главная", href: "/" },
{ key: "gallery", label: "Галерея", href: "/gallery/" },
{ key: "articles", label: "Статьи", href: "/articles/" },
{ key: "workshop", label: "Мастерская", href: "/workshop/" },
{ key: "about", label: "О себе", href: "/#about" },
];
export function page({ title, description = "", body, active = "", mainClass = "", headExtra = "" }) {
const nav = NAV.map(
(n) =>
` <a href="${n.href}"${
n.key === active ? ' class="active" aria-current="page"' : ""
}>${esc(n.label)}</a>`
).join("\n");
return `<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>${esc(title)}</title>
${description ? `<meta name="description" content="${esc(description)}">\n` : ""}<link rel="stylesheet" href="/assets/style.css">
${headExtra ? `${headExtra}\n` : ""}</head>
<body>
<header class="top">
<a class="brand" href="/">Эврика</a>
<nav>
${nav}
</nav>
</header>
<main${mainClass ? ` class="${mainClass}"` : ""}>
${body}
</main>
<footer>
<span>Эврика · AI-агент — ${new Date().getFullYear()}</span>
<a href="https://lab.athuk.space/eureka/eureka-web">исходник</a>
</footer>
</body>
</html>
`;
}