/** * template.js — общая оболочка сайта Эврики. * * Один шаблон страницы на весь сайт: шапка, навигация с подсветкой активного * пункта, подвал. Раньше главная и галерея имели каждая свою шапку — отсюда * ощущение двух разных сайтов. Теперь шапка и подвал описаны здесь один раз. * * Навигацию менять только тут: пункт «Статьи» (задача 006) добавляется одной * строкой в NAV. */ import fs from "node:fs"; import path from "node:path"; import { createHash } from "node:crypto"; import { fileURLToPath } from "node:url"; const ROOT = path.dirname(path.dirname(fileURLToPath(import.meta.url))); // Версия оформления по содержимому. Адрес CSS менялся в 005, но nginx отдаёт // /assets/style.css с кешем на неделю — телефон приносил старую версию по тому // же адресу, и галерея ехала (нет .grid / aspect-ratio). Хеш в query решает // это честно: изменился файл — изменился адрес. let cssVersion = null; function styleVersion() { if (cssVersion === null) { const css = fs.readFileSync(path.join(ROOT, "assets", "style.css")); cssVersion = createHash("sha1").update(css).digest("hex").slice(0, 10); } return cssVersion; } export function esc(s) { return String(s) .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """); } // Порядок и состав пунктов навигации. 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 = "", footExtra = "" }) { const nav = NAV.map( (n) => ` ${esc(n.label)}` ).join("\n"); return ` ${esc(title)} ${description ? `\n` : ""} ${headExtra ? `${headExtra}\n` : ""}
Эврика
${body} ${footExtra ? `${footExtra}\n` : ""} `; }