Ви запустили інтернет-магазин на ProcessWire, але сторінки завантажуються по 3 секунди, а LCP зашкалює? Стандартна тема додала купу зайвих скриптів, а верстка не адаптується під потрібні дані. Кастомний шаблон вирішує це — ви отримуєте рівно те, що потрібно, без сміття. За 8 років роботи з ProcessWire ми накопичили досвід, що дозволяє гарантувати надійне рішення. Перехід на кастомні шаблони знижує TTFB у 2–3 рази за рахунок виключення невикористовуваних модулів.
Як розробити кастомний шаблон ProcessWire?
Шаблон у ProcessWire — PHP-файл у /site/templates/, ім'я якого збігається з ім'ям шаблону в базі. Файл отримує об'єкт $page з даними поточної сторінки та повний доступ до $pages, $config, $user та решти API. Чистий PHP — жодного двигуна за замовчуванням, хоча можна підключити Twig через модуль TemplateEngineTwig. Для продакшену ми рекомендуємо чистий PHP: він швидший і не додає зайвий шар абстракції.
Чому кастомний шаблон кращий за стандартний?
Стандартні теми часто перевантажені невикористовуваними скриптами та стилями, що збільшує LCP і CLS. Кастомний шаблон виводить лише потрібні дані, використовує server-side rendering для важких компонентів та впроваджує lazy loading для зображень. В одному з наших проєктів — інтернет-магазин на ProcessWire з 5000+ товарів — перехід на кастомні шаблони знизив споживання пам'яті на 60% і прискорив генерацію сторінок у 2 рази. Додатково ми зменшили кількість запитів до БД з 50 до 3 на сторінку.
Архітектура шаблонів: варіанти розділення
Варіант 1: _init.php + _main.php
Найпоширеніший підхід. ProcessWire автоматично включає _init.php перед кожним шаблоном та _main.php після, якщо увімкнено опцію «Prepend/Append template file» в налаштуваннях шаблону:
// _init.php і _main.php — єдиний потік $baseUrl = $config->urls->root; $homePage = $pages->get("/"); $mainNav = $pages->find("parent=/,template!=error404,sort=sort"); ?><!DOCTYPE html> <html lang="<?= $user->language->name ?>"> <head> <meta charset="utf-8"> <title><?= $page->title ?> | <?= $homePage->title ?></title> <link rel="stylesheet" href="<?= $config->urls->templates ?>css/main.css"> </head> <body> <?php include("partials/nav.php"); ?> <main><?= $content ?></main> <?php include("partials/footer.php"); ?> </body> </html> Варіант 2: контролер + вид Для складних шаблонів логіку виносять в окремий файл-контролер. Це спрощує підтримку та тестування:
// templates/services.php — точка входу require __DIR__ . '/controllers/services.php'; extract($viewData); require __DIR__ . '/views/services.view.php'; // templates/controllers/services.php — контролер $viewData = [ 'items' => $pages->find("template=service, sort=sort, limit=12"), 'categories' => $pages->find("template=service-category, sort=sort"), 'pagination' => $modules->get("MarkupPagerNav"), ]; Порівняння підходів
| Характеристика | init/main | controller+view |
|---|---|---|
| Складність | Низька | Середня |
| Підтримка | Проста | Гнучка |
| Тестованість | Низька | Висока |
| Продуктивність | Висока | Висока |
| Рекомендація | Невеликі проєкти | Складні проєкти |
Робота із зображеннями
ProcessWire обробляє зображення на льоту через метод size(). Приклад із WebP:
$img = $page->images->first(); if ($img) { $thumb = $img->size(800, 600, ['cropping' => 'center', 'quality' => 85]); echo "<img src='{$thumb->url}' alt='{$img->description}' loading='lazy'>"; $webp = $img->size(800, 600, ['suffix' => 'webp', 'webpAdd' => true]); } Кастомні 404 та редиректи
if ($page->redirect_url) { $session->redirect($page->redirect_url, 301); } if (!$user->isLoggedin() && $page->requires_login) { throw new Wire404Exception(); } Як оптимізувати зображення: покрокова інструкція
- Виберіть зображення з галереї сторінки.
- Викличте
$img->size()з потрібними параметрами. - Вкажіть
suffix: 'webp'іwebpAdd: trueдля генерації WebP. - Додайте атрибут
loading='lazy'для відкладеного завантаження. - Використовуйте
$pages->findMany()для масової конвертації на високонавантажених сайтах.
Продуктивність: ліниве завантаження зв'язків
За замовчуванням FieldtypePage завантажує пов'язані об'єкти при зверненні. При великих списках використовуйте $pages->findMany() — потокова обробка без завантаження всього в пам'ять:
foreach ($pages->findMany("template=product, sort=title") as $product) { echo $product->title . "\n"; } Деталі про findMany()
Метод findMany() обробляє сторінки по одній, не зберігаючи їх у пам'ять. Це особливо важливо на сторінках із тисячами товарів. Він працює як генератор: при кожній ітерації завантажується лише поточна сторінка.Типові терміни розробки шаблонів
| Задача | Оцінка |
|---|---|
| Базовий шаблон (layout + nav + footer) | 4–8 год |
| Шаблон списку з пагінацією та фільтром | 8–16 год |
| Детальна сторінка зі зв'язками | 4–10 год |
| Система шаблонів для 10+ типів контенту | 3–6 днів |
| Інтеграція Twig + компонентний підхід | 2–4 дні |
Що входить у розробку?
- Архітектура шаблонів (init/main або controller+view)
- Налаштування prepend/append файлів
- Верстка всіх типових сторінок (список, детальна, 404)
- Оптимізація зображень (size, WebP, lazy loading)
- Базова SEO-розмітка (meta title, description, og:image)
- Документація по шаблонах і доступах
- Навчання команди замовника (1 година онлайн)
- Гарантія на код 3 місяці
Навчання та документація — окремий пункт: ми передаємо знання, щоб ви могли підтримувати проєкт самостійно.
Типові проблеми та їх вирішення
Невикористання буферизації виводу при prepend/append призводить до дублювання заголовків. Рішення — завжди вмикати prepend/append або застосовувати патерн контролера. Завантаження всіх пов'язаних сторінок одразу — для наборів більше 100 записів використовуйте $pages->findMany(). Ігнорування кешу зображень: ProcessWire кешує варіанти, але при частій зміні контенту очищайте кеш у /site/assets/files/. 404-сторінка обов'язкова: завжди викидайте Wire404Exception для захищених розділів.
Зв'яжіться з нами для безкоштовної консультації — обговоримо ваш проєкт. Замовте розробку кастомного шаблону ProcessWire та отримайте гнучкість і продуктивність.
Детальніше про атрибут loading на MDN — Wikipedia Core Web Vitals — метрики продуктивності.







