Розробка кастомного блока Concrete CMS
Блок (Block) — базовий елемент контенту в Concrete CMS. Вбудовані блоки (Content, Image, Form) покривають типові завдання, але нестандартна функціональність вимагає розробки власних блоків. Кастомний блок — це PHP-клас з формою редагування, шаблоном виводу та схемою зберігання даних.
Структура блока
Блок розташовується в 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>
Concrete CMS автоматично створює та оновлює таблиці при встановленні/оновленні пакету.
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;
}
}
Кешування блока
Параметри кешу задаються в контролері:
protected $btCacheBlockRecord = true; // кеш запису БД
protected $btCacheBlockOutput = true; // кеш HTML-виводу
protected $btCacheBlockOutputLifetime = 3600; // TTL у секундах
// При наявності редактуємого контенту:
protected $btCacheBlockOutputOnPost = false; // не кешувати після POST
Сроки розробки блока
| Складність | Опис | Срок |
|---|---|---|
| Простий | Текст + зображення + посилання | 4–8 ч |
| Середній | Список елементів, галерея, табы | 1–2 дні |
| Складний | Інтеграція з API, кастомний JS | 2–5 днів |







