Проект на Concrete CMS розростається. Блоки множаться, теми правляться наживо, а перенесення функціоналу між інсталяціями перетворюється на ручну перепис. Типова ситуація: клієнт замовляє блок «картка товару», потім ще один, потім тему. Через пів року — шість блоків, дві теми, три кастомних атрибути — і жоден із них не переноситься на новий сайт без танців із бубном. Рішення — упакувати все в один кастомний пакет.
Наші інженери з 5-річним досвідом розробки для Concrete CMS допомагають перетворити розрізнені напрацювання на єдиний, перевикористовуваний модуль. За цей час ми реалізували понад 30 пакетів для корпоративних клієнтів — від простих наборів блоків до повнофункціональних модулів із REST API, Doctrine-сутностями та фоновими завданнями. Економія на кожному розгортанні сягає 90% часу, що знижує сукупну вартість володіння до 40%. Зв'яжіться з нами, щоб обговорити ваш проект, — консультація надається протягом дня.
Економія при використанні кастомного пакета
Ручне встановлення кожного компонента окремо призводить до дублювання коду, помилок при оновленні схеми бази даних і неконтрольованих версій. Кастомний пакет вирішує ці проблеми. Один файл controller.php автоматично встановлює блоки, теми, атрибути, типи сторінок і завдання Cron. Порівняйте: при ручному встановленні на новий сайт ви витрачаєте від 2 до 5 годин на поштучне налаштування кожного компонента. Пакет встановлюється за 5 хвилин. Економія часу — в 10–20 разів на кожному розгортанні.
Як влаштований кастомний пакет у Concrete CMS?
Пакет — це просто папка з чіткою структурою. Головний файл — controller.php, який описує залежності та автоматично встановлює всі компоненти.
packages/my-package/
controller.php
blocks/
feature-card/
controller.php
db.xml
add.php
edit.php
view.php
themes/
my-theme/
attributes/
color_picker/
controller.php
single_pages/
dashboard/my_package/settings.php
elements/my_package/settings_form.php
jobs/sync_products.php
src/Entity/Order.php
src/Repository/OrderRepository.php
src/Service/OrderService.php
db.xml
Ключові компоненти пакета
-
controller.php— реєструє пакет, встановлює блоки, типи сторінок, атрибути та Dashboard-сторінки. - Блоки — кастомні елементи інтерфейсу (feature-card, team-member).
- Теми — глобальний дизайн сайту.
- Атрибути — користувацькі поля для сторінок і блоків.
- Single pages — сторінки налаштувань у Dashboard.
- Cron Jobs — фонові завдання (синхронізація, відправка листів).
- Doctrine-сутності — робота з таблицями через ORM.
- REST API — кастомні ендпоінти для інтеграцій.
Контролер пакета
Серце пакета — клас Controller, що успадковує Concrete\Core\Package\Package. У ньому описуються встановлення, оновлення та видалення компонентів.
<?php
namespace Concrete\Package\MyPackage;
use Concrete\Core\Package\Package;
use Concrete\Core\Page\Single as SinglePage;
use Concrete\Core\Block\BlockType\BlockType;
use Concrete\Core\Page\Type\Type as PageType;
use Concrete\Core\Attribute\Type as AttributeType;
use Concrete\Core\Job\Job;
defined('C5_EXECUTE') or die('Access Denied.');
class Controller extends Package {
protected string $pkgHandle = 'my-package';
protected string $appVersionRequired = '9.0.0';
protected string $pkgVersion = '2.1.0';
public function getPackageName(): string { return t('My Package'); }
public function getPackageDescription(): string { return t('Повний функціональний пакет для корпоративного сайту'); }
public function on_start(): void {
$this->app->make(\Concrete\Package\MyPackage\Routing\RouteRegistrar::class)->register();
$this->app->make('Concrete\Core\Foundation\Service\ProviderList')
->registerProvider(\Concrete\Package\MyPackage\Provider\ServiceProvider::class);
}
public function install(): void {
$pkg = parent::install();
$this->installOrUpgrade($pkg);
}
public function upgrade(): void {
parent::upgrade();
$pkg = $this->getPackageEntity();
$this->installOrUpgrade($pkg);
}
private function installOrUpgrade(\Concrete\Core\Entity\Package $pkg): void {
$this->installBlock('feature-card', $pkg);
$this->installBlock('team-member', $pkg);
$this->installBlock('testimonial', $pkg);
$this->installPageType('service-detail', 'Service Detail', $pkg);
$this->installPageType('team-member', 'Team Member', $pkg);
$this->installPageAttribute('hero_image', 'image', 'Hero Image', $pkg);
$this->installPageAttribute('intro_text', 'text', 'Intro Text', $pkg);
$this->installPageAttribute('meta_description', 'textarea', 'Meta Description', $pkg);
$this->installPageAttribute('show_in_nav', 'boolean', 'Show in Navigation', $pkg);
$sp = SinglePage::add('/dashboard/my_package', $pkg);
if ($sp) $sp->update(['cName' => 'My Package', 'cDescription' => 'Налаштування']);
$sp = SinglePage::add('/dashboard/my_package/settings', $pkg);
if ($sp) $sp->update(['cName' => 'Settings']);
Job::installByPackage('sync_products', $pkg);
}
private function installBlock(string $handle, $pkg): void {
if (!BlockType::getByHandle($handle)) {
BlockType::installBlockTypeFromPackage($handle, $pkg);
}
}
private function installPageType(string $handle, string $name, $pkg): void {
if (!PageType::getByHandle($handle)) {
PageType::add(['ptHandle' => $handle, 'ptName' => $name, 'ptIsFrequentlyAdded' => 0, 'ptLaunchInComposer' => 1], $pkg);
}
}
private function installPageAttribute(string $handle, string $type, string $name, $pkg): void {
$at = AttributeType::getByHandle($type);
$ak = \Concrete\Core\Attribute\Key\CollectionKey::getByHandle($handle);
if (!$ak) {
\Concrete\Core\Attribute\Key\CollectionKey::add($at, ['akHandle' => $handle, 'akName' => $name], $pkg);
}
}
public function uninstall(): void {
parent::uninstall();
$db = $this->app->make('database')->connection();
$db->executeStatement('DROP TABLE IF EXISTS MyPackageOrders');
}
}
Порівняння: кастомний пакет vs ручне встановлення
| Критерій | Кастомний пакет | Ручне встановлення |
|---|---|---|
| Час розгортання | Одна команда zip → встановлення через адмінку |
Поштучне встановлення блоків, тем, атрибутів |
| Версіонування | Єдине керування через pkgVersion і db.xml |
Немає контролю версій |
| Переносимість | Встановлення на будь-який сайт за 5 хвилин | Потрібне копіювання кожного компонента |
| Підтримка | Автоматичне оновлення схеми БД | Ручні міграції |
Кастомний пакет прискорює розгортання в 3–5 разів і повністю виключає помилки ручного складання. Гарантуємо сумісність з останніми версіями Concrete CMS.
Процес розробки пакета
- Аналіз вимог — визначаємо склад пакета (блоки, теми, атрибути, сутності, API).
- Проєктування архітектури — схема БД, структура класів, маршрути.
- Реалізація — написання контролера, блоків, сутностей, завдань.
- Тестування — перевірка встановлення, оновлення, видалення на тестовому сайті.
- Документування — інструкції, опис API, приклади.
- Деплой — упаковка, передача клієнту.
Що входить у розробку пакета
- Вихідний код у Git-репозиторії.
- Документація: встановлення, налаштування, адміністрування.
- Навчання команди (1–2 години).
- Гарантія 6 місяців на підтримку та виправлення багів.
- Безкоштовне оновлення при виході нової версії CMS (протягом гарантійного терміну).
Які типові помилки вирішує пакет?
Розглянемо реальний випадок. Клієнт розробив 6 блоків вручну, але на новому сайті блоки не відображалися через відсутність залежностей у db.xml. Довелося перевстановлювати кожен блок, правити міграції — втратили 3 дні. З пакетом ми вирішили це за 2 години: описали всі блоки в контролері, додали автоматичне створення таблиць через db.xml і протестували встановлення на чистому ядрі. Більше жодних помилок при перенесенні.
Коли варто замовляти кастомний пакет?
Пакет виправданий, якщо ви плануєте використовувати однаковий функціонал на кількох сайтах, хочете стандартизувати розробку або потребуєте гарантованої переносимості компонентів. Якщо проект разовий і не передбачає розширення, можливо, достатньо ручного встановлення. Але в більшості корпоративних сценаріїв пакет окупається вже на другому впровадженні.
Строки розробки пакета
| Компонент | Оцінка |
|---|---|
| Контролер пакета + встановлення | 4–8 год |
| 3–5 кастомних блоків | 3–6 днів |
| Тема з 8–12 типами сторінок | 2–4 тижні |
| Doctrine-сутності + CRUD | 2–4 дні |
| Dashboard-сторінка + налаштування | 1–2 дні |
| REST API (3–5 ендпоінтів) | 2–3 дні |
| Cron Jobs (1–3 завдання) | 4–8 год |
| Повний корпоративний пакет | 8–16 тижнів |
Детальніше про Concrete CMS можна прочитати на Wikipedia.
Замовте розробку кастомного пакета — отримайте консультацію протягом дня. Зв'яжіться з нами, щоб обговорити ваш проект.







