Розробка кастомного шаблону ProcessWire

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка кастомного шаблону ProcessWire
Середня
~5 робочих днів
Часті питання

Наші компетенції:

Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розробка кастомного шаблону ProcessWire

Шаблон в ProcessWire — це PHP-файл у /site/templates/, ім'я якого збігається з іменем шаблону в базі. Файл отримує об'єкт $page з даними поточної сторінки та повний доступ до $pages, $config, $user та решти API. Жодного рушія шаблонів за замовчуванням — чистий PHP, хоча можна підключити Twig через модуль TemplateEngineTwig.

Архітектура шаблонів: варіанти розділення

Варіант 1: _init.php + _main.php

Найпоширеніший підхід. ProcessWire автоматично включає _init.php перед кожним шаблоном та _main.php після, якщо включена опція «Prepend/Append template file» у налаштуваннях шаблону.

// _init.php — глобальні змінні, хелпери
$baseUrl  = $config->urls->root;
$homePage = $pages->get("/");
$mainNav  = $pages->find("parent=/,template!=error404,sort=sort");

function formatDate(int $ts): string {
    return date("d.m.Y", $ts);
}
// _main.php — layout-обгортка
?><!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>

У шаблоні сторінки $content накопичується через буферизацію виводу:

// services.php — ProcessWire автоматично буферизує вивід
$items = $pages->find("template=service, parent={$page}, sort=sort");
foreach ($items as $item) {
    echo "<article>";
    echo "<h2><a href='{$item->url}'>{$item->title}</a></h2>";
    echo "<p>{$item->summary}</p>";
    echo "</article>";
}

Варіант 2: контролер + вид

Для складних шаблонів логіку виносять у окремий файл-контролер:

templates/
  controllers/
    services.php     # тільки логіка, без echo
  views/
    services.view.php # тільки розмітка
  services.php         # точка входу, зв'язує controller+view
// 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"),
];

Робота з зображеннями

ProcessWire обробляє зображення на льоту через метод size():

// Головне зображення сторінки
$img = $page->images->first();
if ($img) {
    // Ресайз з кадруванням 800×600
    $thumb = $img->size(800, 600, ['cropping' => 'center', 'quality' => 85]);
    echo "<img src='{$thumb->url}' alt='{$img->description}' loading='lazy'>";

    // WebP через опцію suffix
    $webp = $img->size(800, 600, ['suffix' => 'webp', 'webpAdd' => true]);
}

Варіантні розміри кешуються у /site/assets/files/{id}/. Повторний запрос повертає вже готовий файл.

Повторно використовувані часткові шаблони

// partials/card.php — отримує $item з include
?>
<div class="card">
    <?php if ($item->image): ?>
        <img src="<?= $item->image->size(400,300)->url ?>" alt="<?= $item->title ?>">
    <?php endif; ?>
    <h3><?= $item->title ?></h3>
    <p><?= $item->summary ?></p>
    <a href="<?= $item->url ?>">Детальніше</a>
</div>
// Використання у services.php
foreach ($items as $item) {
    include("./partials/card.php");
}

Мета-дані та SEO

SEO-поля звичайно додають на рівні шаблону через окремий fieldset:

// У _main.php
$metaTitle       = $page->meta_title ?: $page->title;
$metaDescription = $page->meta_description ?: $page->summary;
$ogImage         = $page->og_image ? $page->og_image->size(1200, 630)->httpUrl : '';
?>
<title><?= htmlspecialchars($metaTitle) ?></title>
<meta name="description" content="<?= htmlspecialchars($metaDescription) ?>">
<meta property="og:image" content="<?= $ogImage ?>">

Кастомні 404 та редиректи

// templates/basic-page.php
// Редирект застарілого URL
if ($page->redirect_url) {
    $session->redirect($page->redirect_url, 301);
}

// Примусовий 404
if (!$user->isLoggedin() && $page->requires_login) {
    throw new Wire404Exception();
}

Продуктивність: ленива загрузка зв'язків

За замовчуванням FieldtypePage завантажує пов'язані об'єкти при звертанні. При великих списках використовують $pages->findMany() — потокова обробка без завантаження всього в пам'ять:

// findMany() для великих наборів (1000+ сторінок)
foreach ($pages->findMany("template=product, sort=title") as $product) {
    echo $product->title . "\n";
    // ProcessWire автоматично звільняє пам'ять
}

Сроки розробки шаблонів

Завдання Оцінка
Базовий шаблон (layout + nav + footer) 4–8 ч
Шаблон списку з пагінацією та фільтром 8–16 ч
Детальна сторінка зі зв'язками 4–10 ч
Система шаблонів для 10+ типів контенту 3–6 днів
Інтеграція Twig + компонентний підхід 2–4 дні