Кастомні блоки Concrete CMS: створення, кешування, валідація

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

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

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

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Кастомні блоки Concrete CMS: створення, кешування, валідація
Середній
~2-3 дні
Часті запитання

Коли стандартних блоків Concrete CMS недостатньо?

Вбудовані блоки (Content, Image, Form) покривають 80% типових завдань. Але інші 20% — наприклад, картка переваги з іконкою, посиланням і вибором макету — вимагають власного блоку. Ми створили десятки таких блоків: від простих текстових плашок до інтеграцій із зовнішніми API. За 7+ років на ринку ми виконали 50+ проектів. Досвідчений інженер спроектує кастомний блок так, що час внесення правок скоротиться на 40%, а дублювання коду зникне. В одному інтернет-магазині ми замінили три різні плагіни одним блоком Feature Card — LCP впав на 300 мс, підтримка спростилася. Економія бюджету на плагінах склала до 50% (економія близько $500 на рік). Якщо ви зіткнулися з цими проблемами — замовте розробку кастомного блоку, і ми запропонуємо ефективне рішення.

Три типові проблеми, які вирішує кастомний блок

  1. Негнучкість стандартних блоків. Ви не додасте поле для іконки або перемикач макету в блок Content — тільки через кастом. 2. Дублювання коду. Якщо однаковий набір полів використовується на кількох сторінках, без кастомного блоку доведеться копіювати HTML у кожен редактор. 3. Кешування. Стандартні блоки кешуються за замовчуванням, але для складних структур потрібно налаштовувати параметри вручну — у власному контролері це робиться парою рядків.

Як ми розробляємо кастомні блоки

Використовуємо перевірену архітектуру: контролер відповідає за валідацію та збереження даних, шаблон — тільки за виведення. Для зберігання полів застосовуємо db.xml, керуємо файлами через Concrete\Core\File\File. Розглянемо блок Feature Card для інтернет-магазину: 4 макети, іконка з файлового менеджера, кешування виведення з TTL 3600 секунд.

Покрокова інструкція зі створення блоку

  1. Створіть структуру каталогу: blocks/feature-card/ з файлами controller.php, db.xml, add.php, edit.php, view.php, icon.png (48×48). Для альтернативних шаблонів додайте папку templates/.
  2. Опишіть схему БД у db.xml: визначте поля, їх типи та ключі. Concrete CMS автоматично створить таблицю при встановленні пакету.
  3. Реалізуйте контролер: успадкуйте BlockController, задайте властивості кешування та таблиці, перевизначте методи add(), edit(), view(), save() та validate().
  4. Створіть шаблони виведення: view.php для відображення, альтернативні шаблони в templates/ для різних макетів.
  5. Встановіть блок: через пакет або безпосередньо в application/blocks/ — він з'явиться в редакторі сайту.

Структура блоку

Блок розташовується в packages/my-package/blocks/my-block/ або application/blocks/my-block/:

blocks/feature-card/
 controller.php # логіка, валідація, CRUD
 db.xml # схема таблиці БД
 add.php # форма додавання блоку
 edit.php # форма редагування (зазвичай include add.php)
 view.php # шаблон виведення на сторінці
 icon.png # іконка (48×48)
 templates/ # альтернативні шаблони виведення
 compact.php

db.xml — схема зберігання даних

<?xml version="1.0"?>
<schema version="0.3">
  <table name="btFeatureCard">
    <field name="bID" type="I">
      <KEY/>
      <UNSIGNED/>
    </field>
    <field name="headline" type="C" size="255"/>
    <field name="subheadline" type="C" size="255"/>
    <field name="body" type="X2"/>
    <field name="link_url" type="C" size="512"/>
    <field name="link_text" type="C" size="100"/>
    <field name="icon_fID" type="I">
      <UNSIGNED/>
    </field>
    <field name="layout" type="C" size="50">
      <DEFAULT value="default"/>
    </field>
  </table>
</schema>

controller.php

<?php

namespace Concrete\Package\MyPackage\Block\FeatureCard;

use Concrete\Core\Block\BlockController;
use Concrete\Core\File\File;

defined('C5_EXECUTE') or die('Access Denied.');

class Controller extends BlockController
{
    protected $btTable = 'btFeatureCard';
    protected $btInterfaceWidth = 600;
    protected $btInterfaceHeight = 500;
    protected $btCacheBlockRecord = true;
    protected $btCacheBlockOutput = true;

    public function getBlockTypeName(): string
    {
        return 'Feature Card';
    }

    public function getBlockTypeDescription(): string
    {
        return 'Картка переваги з іконкою та посиланням';
    }

    public function add(): void
    {
        $this->set('layout_options', ['default' => 'Стандартний', 'horizontal' => 'Горизонтальний']);
    }

    public function edit(): void
    {
        $this->add();
        if ($this->icon_fID) {
            $this->set('icon_file', File::getByID($this->icon_fID));
        }
    }

    public function view(): void
    {
        if ($this->icon_fID) {
            $this->set('iconFile', File::getByID($this->icon_fID));
        }
    }

    public function save(array $args): void
    {
        $args['headline'] = strip_tags($args['headline'] ?? '');
        $args['subheadline'] = strip_tags($args['subheadline'] ?? '');
        $args['body'] = $args['body'] ?? '';
        $args['link_url'] = filter_var($args['link_url'] ?? '', FILTER_SANITIZE_URL);
        $args['link_text'] = strip_tags($args['link_text'] ?? '');
        $args['icon_fID'] = (int)($args['icon_fID'] ?? 0);
        $args['layout'] = in_array($args['layout'], ['default', 'horizontal']) ? $args['layout'] : 'default';
        parent::save($args);
    }

    public function validate(array $args): \Concrete\Core\Error\ErrorList\ErrorList
    {
        $e = $this->app->make('error');
        if (empty(trim($args['headline'] ?? ''))) {
            $e->add('Заголовок обов\'язковий');
        }
        return $e;
    }
}

view.php

<?php defined('C5_EXECUTE') or die('Access Denied.'); ?>
<div class="feature-card feature-card--<?= h($layout) ?>">
  <?php if ($iconFile): ?>
    <div class="feature-card__icon">
      <img src="<?= $iconFile->getRelativePath() ?>" alt="">
    </div>
  <?php endif; ?>
  <div class="feature-card__body">
    <?php if ($headline): ?><h3><?= h($headline) ?></h3><?php endif; ?>
    <?php if ($subheadline): ?><p class="subheadline"><?= h($subheadline) ?></p><?php endif; ?>
    <?php if ($body): ?><div class="text"><?= nl2br(h($body)) ?></div><?php endif; ?>
    <?php if ($link_url && $link_text): ?>
      <a href="<?= h($link_url) ?>" class="btn"><?= h($link_text) ?></a>
    <?php endif; ?>
  </div>
</div>

Офіційна документація Concrete CMS описує мінімальний набір файлів: controller.php, db.xml, add.php, edit.php, view.php. Детальніше про розробку блоків — в офіційній документації.

Як налаштувати кешування для блоку?

Параметри кешу задаються в контролері. Встановлення btCacheBlockRecord та btCacheBlockOutput в true вмикає кеш запису та HTML-виведення. TTL керується властивістю btCacheBlockOutputLifetime. Для блоків з POST-даними обов'язково вимикати кеш після відправки: btCacheBlockOutputOnPost = false. Це запобігає показу застарілого контенту після редагування. Правильна конфігурація кешування знижує TTFB на 100–200 мс.

Блок з кількома записами (список елементів)

Для блоків типу «список елементів» використовується btExportTables та дочірня таблиця. У контролері вкажіть protected $btExportTables = ['btFeatureList', 'btFeatureListItems'];. Збереження дочірніх записів виконується в методі save(): спочатку видаляються старі, потім вставляються нові з урахуванням сортування.

Приклад структури дочірньої таблиці
<field name="sort" type="I">
  <UNSIGNED/>
  <DEFAULT value="0"/>
</field>

Терміни розробки блоку

Складність Опис Термін Вартість
Простий Текст + зображення + посилання 4–8 год від $200
Середній Список елементів, галерея, таби 1–2 дні від $500
Складний Інтеграція з API, кастомний JS 2–5 днів від $1200

Що входить в роботу

  • Контролер, шаблони (view + альтернативні), схема БД (db.xml).
  • Валідація полів та безпечна обробка даних.
  • Кешування виведення з оптимальним TTL.
  • Міграція існуючих даних (якщо потрібно).
  • Документація зі встановлення та використання.
  • Навчання редакторів роботі з блоком.
  • Гарантія 6 місяців на код.

Прискорення розробки за допомогою альтернативних шаблонів

Використовуйте альтернативні шаблони — це дозволяє змінювати зовнішній вигляд без зміни логіки. Для однотипних блоків (наприклад, кілька варіантів карток) створіть один контролер з перемикачем макету у формі редагування. Це скорочує час розробки в 2–3 рази.

Порівняння: кастомний блок vs готові рішення

Критерій Кастомний блок Готовий плагін
Гнучкість Повна Обмежена налаштуваннями
Продуктивність Оптимізований під задачу Часто надлишковий
Сумісність з оновленнями Контролюється Може зламатися
Час впровадження 4 год – 5 днів 1–2 дні (якщо підходить)
Вартість ліцензії Безкоштовно (власна розробка) $50–$500/рік

Кастомні блоки в 3 рази швидше завантажуються при правильному кешуванні — LCP знижується на 200–400 мс. Економія бюджету за рахунок відмови від плагінів може становити до 50% (до $500 на рік).

Оцінимо ваш проект за 1 робочий день. Просто напишіть нам — ми підберемо оптимальне рішення для ваших завдань.

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

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

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