Скины шаблонизатора: TemplateSneat против своего лёгкого скина
Шаблонизатор двухслойный. Template генерит <!DOCTYPE>, <head> и <body>, даёт методы header(), footer(), mainmenu(), add_head_css(), add_head_js(). Скин - отдельный класс, который по duck-typed контракту решает, чем эту оболочку наполнить. Интерфейс не навязан: движок просто вызывает нужные методы, если они есть.
Контракт скина
get_head_css_urls(): arrayget_head_js_urls(): array- элементы{src, defer}get_body_class(): stringget_body_attributes(): arrayrender_body_open(): voidrender_body_close(): voidmainmenu(): void
Готовые скины: TemplateSneat (админка на купленном Bootstrap-макете), TemplateBasePage и TemplateBlog (лёгкий холст под контент).
TemplateSneat: мощь и её цена
Sneat - это полноценная админ-панель: меню, дропдауны, модалки, готовые компоненты Bootstrap 5. За это платишь дисциплиной порядка вендорных скриптов:
// Канонический порядок вендорного JS Sneat-подобного макета.
// Порядок - это зависимости, не алфавит; пропуск даёт молчаливые баги
// на конкретных интеракциях (меню, скролл), без ошибок в консоли:
helpers.js
-> config.js // задаёт window.templateName / window.config
-> bootstrap.js
-> perfect-scrollbar.js // обязателен для menu.js
-> menu.js
-> init (кастомный) // всегда последнимИ парой граблей, которые стоит знать заранее:
- TemplateCustomizer в сборке мёртв. В бандле остался только вызов
new TemplateCustomizer({...}), обёрнутый вif (typeof TemplateCustomizer !== 'undefined'), а самого класса нет. Не тащить его - сделать тонкий слой поверхwindow.Helpers. - Wide-контент - это
container-fluid, а неcontainer-xxl. Меняется в трёх местах: navbar, content, footer. Классlayout-compactза ширину не отвечает. - Тему и свёрнутое меню применять до отрисовки - инлайн-скриптом в
render_body_open(), читающим тот же ключlocalStorage, иначе интерфейс моргает при загрузке.
Свой лёгкий скин
Для лендинга Sneat - это мегабайты вендорного CSS и JS ради страницы, которой не нужен ни один Bootstrap-компонент. Лёгкий скин - это класс на полсотни строк: свой CSS, ноль вендорного JS, а шрифты ядра (Archivo, Figtree, IBM Plex Mono) уже в <head> от Template.
<?php
declare(strict_types=1);
final class TemplateLanding
{
/** @return array<int, string> */
public function get_head_css_urls(): array
{
return ['/page/landing/landing.css'];
}
/** @return array<int, array{src:string, defer:bool}> */
public function get_head_js_urls(): array
{
return []; // лендингу вендорный JS не нужен вообще
}
public function get_body_class(): string
{
return 'lp lp-dark';
}
/** @return array<string, string> */
public function get_body_attributes(): array
{
return ['data-theme' => 'dark'];
}
public function render_body_open(): void
{
echo '<div class="lp-shell">';
}
public function render_body_close(): void
{
echo '</div>';
}
public function mainmenu(): void
{
echo '<nav class="lp-nav">'
. '<a href="/">SG</a>'
. '<a href="/features">Возможности</a>'
. '<a href="/blog">Блог</a>'
. '</nav>';
}
}Как выбирать
- Админ-CRUD с меню, таблицами, модалками и дропдаунами -
TemplateSneat. Готовые Bootstrap-компоненты уже оплачены, глупо писать их заново. - Контентная страница или лендинг - свой лёгкий скин. Не платить трафиком и временем загрузки за админ-вендор, который тут не работает.
И общее для обоих: файл скина - UTF-8 без BOM. BOM перед <?php роняет strict_types с ошибкой "declaration must be the very first statement". Проверяется по первым байтам 3C 3F 70 68 70.