В блог
14 июля 2026 Sogerien bootstraptemplatesneatскиныфронтендшаблонизатор

Скины шаблонизатора: TemplateSneat против своего лёгкого скина

Шаблонизатор двухслойный. Template генерит <!DOCTYPE>, <head> и <body>, даёт методы header(), footer(), mainmenu(), add_head_css(), add_head_js(). Скин - отдельный класс, который по duck-typed контракту решает, чем эту оболочку наполнить. Интерфейс не навязан: движок просто вызывает нужные методы, если они есть.

Контракт скина

  • get_head_css_urls(): array
  • get_head_js_urls(): array - элементы {src, defer}
  • get_body_class(): string
  • get_body_attributes(): array
  • render_body_open(): void
  • render_body_close(): void
  • mainmenu(): 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.