Розробка кастомного модуля ProcessWire: хуки, Fieldtype, Process

Стандартних можливостей CMS часто не вистачає під ваші процеси, і команда починає вручну переносити дані. Ми розробляємо кастомні модулі ProcessWire під ключ: автоматизуємо рутину, прибираємо помилки ручного введення і скорочуємо час операцій. Обговоримо задачу — повернемося з оцінкою та планом.

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка кастомного модуля ProcessWire: хуки, Fieldtype, Process
Середній
~3-5 днів
Часті запитання

Коли стандартної логіки CMS не вистачає: кастомний модуль ProcessWire

Штатні поля та шаблони закривають типовий контент-сайт: сторінки, категорії, зв'язки, виведення за умовою.

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

У цей момент штатних полів перестає вистачати, і в шаблонах з'являються обхідні рішення — вибірки в циклі, логіка в розмітці, дубльовані перевірки. Такий код працює до першої правки вимог, а далі кожне доопрацювання тягне за собою переперевірку всього, що поруч.

Розширення CMS через кастомний модуль ProcessWire переносить цю логіку туди, де її видно і можна перевірити: в окремий клас із точками підключення до ядра.

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

Власний тип поля (Fieldtype) описує зберігання та валідацію даних на рівні ядра, тому значення поводиться як штатне: його видно в адмінці, за ним працюють вибірки, воно переживає оновлення.

Процес (Process) додає в панель керування свій екран — наприклад, для запуску синхронізації чи розбору черги, — замість того щоб тримати ці операції в окремих скриптах.

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

Нестандартна логіка перестає бути крихкою надбудовою і стає частиною системи з передбачуваною поведінкою.

Далі розбираємо, як це закривається на практиці: які точки розширення обираємо під задачу, як розділяємо зберігання та поведінку і що залишається замовнику після здачі.

Що дає кастомний модуль ProcessWire: хуки, Fieldtype, Process

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

Перехоплення подій: логіка без правки ядра

Хуки (addHookBefore, addHookAfter, addHookProperty) навішуються на методи ядра і викликаються до або після них.

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

На практиці це прибирає цілий клас регресій — типовий сценарій «правка ядра, яку забули перенести» просто перестає виникати.

Власний тип поля: структура даних замість звалища

Fieldtype у парі з Inputfield описує новий тип поля: як значення зберігається в таблиці, як валідується, як виводиться в редакторі. Замість текстового поля із серіалізованим JSON замовник отримує типізовану структуру — складений адрес, довідник, набір пов'язаних записів.

Вибірки за таким полем ідуть через індекси, а не через розбір рядка на кожному запиті, тому каталог на десятки тисяч сторінок відповідає передбачувано.

Process-модуль: свій розділ адмінки

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

Варіант Коли підходить Обмеження
Хуки Змінюємо поведінку наявної логіки Не створюють нових сутностей і полів
Fieldtype + Inputfield Потрібна нова структура даних із валідацією Вимагає продуманої схеми зберігання
Process-модуль Свій розділ адмінки і права Не впливає на фронтенд-вивід
Зовнішній сервіс Логіка живе поза CMS Дублювання доступу і синхронізація

Механіку зручно перевіряти на живому прикладі — документація ProcessWire описує кожен із трьох інтерфейсів окремо, включно з порядком виклику хуків і вимогами до методів Fieldtype.

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

Як ми проєктуємо та впроваджуємо модуль: від аудиту до передачі

Робота над кастомним модулем ProcessWire виходить із поточного стану проєкту, а не з абстрактного шаблону: спочатку розбираємо, як логіка влаштована сьогодні, потім фіксуємо схему модуля і лише після цього пишемо код.

Такий порядок знімає головний ризик — модуль, який формально працює, але конфліктує з наявними хуками та полями.

  1. Аудит поточної логіки. Дивимося, які хуки вже перехоплюють події, де дублюється бізнес-логіка в шаблонах, які поля та типи сторінок задіяні. На виході — карта точок розширення та список місць, куди вбудовуватися безпечно.
  2. Проєктування модуля. Визначаємо склад: які хуки підключаємо, чи потрібен власний Fieldtype для зберігання даних, чи потрібна Process-сторінка в адмінці для керування. Фіксуємо конфігурацію модуля, права доступу та поведінку при відмові.
  3. Схема даних і міграції. Описуємо, які поля та таблиці з'являються, як вони пов'язані з наявними сторінками, що відбувається при оновленні модуля. Окремо продумуємо оборотність: як відкотитися, якщо нову версію доведеться зняти.
  4. Реалізація. Пишемо модуль із розділенням на шари: хуки відповідають за перехоплення подій, Fieldtype — за зберігання та валідацію, Process — за інтерфейс адміністратора. Логіка не розповзається по шаблонах, її можна змінювати в одному місці.
  5. Перевірка на копії. Розгортаємо модуль на копії бойового сайту з реальними даними: проганяємо сценарії створення, редагування та видалення, перевіряємо поведінку під навантаженням і на граничних випадках. Помилки ловимо до викладки, а не після.
  6. Викладка та моніторинг. Встановлюємо модуль на бойовий сайт із можливістю швидкого вимкнення, стежимо за журналами та відгуком. Якщо щось іде не так — повертаємося до попереднього стану без втрати даних.
  7. Передача коду та документації. Віддаємо репозиторій з історією змін, опис хуків і полів, інструкцію з оновлення та відкату, нотатки щодо конфігурації. Ваші інженери можуть супроводжувати модуль далі без нас.

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

Чим хук відрізняється від власного Fieldtype і коли потрібен Process?

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

Хук не створює нових сутностей — він змінює те, як система обробляє вже наявні дані. Якщо задача звучить як «під час збереження сторінки перерахувати пов'язане поле» або «підмінити вивід у лістингу», точка розширення — хук, і більше нічого городити не потрібно.

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

Це вибір, коли штатних типів не вистачає — наприклад, потрібне поле зі складеним значенням, яке зберігається не як рядок, а як структура, і має коректно поводитися у вибірках, сортуванні та пошуку.

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

Process створює окремий адміністративний розділ — свою сторінку в адмінці зі списком, формами та діями. Він потрібен, коли в задачі є самостійний інтерфейс: імпорт із зовнішнього джерела, масові операції над деревом сторінок, панель налаштувань, не прив'язана до однієї сторінки.

Process не змінює поведінку наявних даних напряму — він дає оператору інструмент, який ці дані створює або змінює.

Вибір точки розширення — це вибір мінімально достатнього втручання. Спершу перевіряємо, чи закриває задачу хук; якщо потрібен новий тип даних — Fieldtype; якщо потрібен окремий екран для роботи з даними — Process.

На практиці архітектура модуля часто комбінує всі три: Process дає адмін-розділ, Fieldtype зберігає структуру, хуки зв'язують їх з рештою системи. Такий поділ залишає кожен шар тестованим окремо і не перетворює модуль на моноліт, який страшно оновлювати.

Кейс: як кастомний модуль прибрав ручну роботу та клас відмов

До впровадження каталог із кількох тисяч карток вівся вручну: контент-менеджер відкривав кожен запис, переносив значення з таблиці постачальника в поля, вручну проставляв категорії та зв'язки між товарами.

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

Помилки були передбачувані й однотипні: дублі карток, биті зв'язки, поля з невірним типом даних. Кожен такий запис ламав вибірки та видачу — сторінка або не відкривалася, або показувала порожній блок. На пошук і виправлення йшло більше часу, ніж на саме завантаження.

Що змінили

Зібрали кастомний модуль ProcessWire, який закриває весь шлях імпорту всередині адмінки. Хук на збереження сторінки перевіряє типи полів і обов'язкові значення до запису в базу — некоректна картка просто не зберігається, а менеджер бачить, яке поле потрібно виправити.

Власний Fieldtype зберігає складений набір атрибутів як єдине значення, тому зв'язки та категорії більше не розсинхронізуються між собою.

Окремий Process додає в адмінку екран пакетного завантаження: файл постачальника розбирається, зіставляється з наявними картками за зовнішнім ідентифікатором, оновлює збіги та створює лише нові записи. Повторний імпорт того самого файлу не плодить дублі — операція ідемпотентна.

Метрики до та після

Показник До Після
Ручних операцій на партію сотні одне завантаження файлу
Час публікації партії кілька годин хвилини
Дублі та биті зв'язки регулярно клас помилок усунуто
Відкат невдалого імпорту ручне виправлення повернення до попереднього стану

Ключовий ефект — не швидкість сама по собі, а зниклий клас відмов: невірні типи та дублі відсікаються на вході, а не виявляються через тиждень у видачі. Логіка перевірок і зіставлення побудована на штатному API ядра ProcessWire, тому оновлення системи не ламає модуль.

Контент-менеджер тепер витрачає час на перевірку результату, а не на перенесення значень. Якщо у вас схожий ручний процес — опишіть задачу, повернемося з оцінкою та планом.

Сумісність, відкат і доступи: що обговорити до старту

Кастомний модуль processwire живе всередині ядра, тому перше, що перевіряємо до старту, — сумісність модуля з поточною гілкою ProcessWire і версіями PHP на ваших серверах.

Якщо проєкт на LTS-гілці, а хостинг тримає старий інтерпретатор, частина API може поводитися інакше: хуки чіпляються, але поведінка змінюється на граничних викликах.

Тому фіксуємо матрицю «версія ядра / версія PHP / використовувані хуки і Fieldtype» і проганяємо її на копії вашого середовища, а не на чистій збірці.

Що якщо оновлення ядра зламає модуль? Ми не патчимо ядро — модуль ставиться окремим пакетом і підключається штатним механізмом. Перед викаткою готуємо безпечний відкат: знімок бази, резервну копію файлів модуля і точку повернення на попередній реліз.

Відкат — це одна операція, а не відновлення з архіву вручну, тому вікно недоступності вимірюється хвилинами.

Як розмежовуються права? Рівні доступу описуємо відразу: ролі в адмінці, права на Process-сторінки, обмеження на поля і операції запису.

Окремо проговорюємо, хто з вашої команди отримує доступ до керування модулем, а хто — лише до контенту, щоб правка налаштувань не залишалася за однією людиною.

Що увійде в передачу документації?

Схема модуля з точками підключення хуків, опис Fieldtype і Process-сторінок, матриця сумісності, інструкція з відкату і розмежування ролей. Плюс регламент оновлення ядра — що перевіряти перед зміною гілки, щоб модуль не відвалився.

На руки ви отримуєте:

  • вихідники модуля з історією змін;
  • схему підключення хуків і кастомних типів полів;
  • матрицю сумісності з версіями ядра і PHP;
  • інструкцію з безпечного відкату і резервного копіювання;
  • опис рівнів доступу і ролей в адмінці;
  • регламент оновлення ядра без втрати працездатності модуля.

Опишіть вашу поточну конфігурацію — версію ядра, хостинг і задачі модуля. Повернемося з оцінкою, планом робіт і списком того, що знадобиться з вашого боку для доступу до середовища.

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

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139
  • Розробка веб-сайту для компанії ФІКСПЕР
    Розробка веб-сайту для компанії ФІКСПЕР
    1060