מתי בלוקים סטנדרטיים של Concrete CMS לא מספיקים
בלוקים מובנים (תוכן, תמונה, טופס) מכסים 80% מהמשימות הטיפוסיות. ה-20% הנותרים—לדוגמה, כרטיס תכונה עם אייקון, קישור ובחירת פריסה—דורשים בלוק מותאם אישית. יצרנו מעל 50 פרויקטים של בלוקים מותאמים אישית, מכרטיסי טקסט פשוטים ועד אינטגרציות עם API חיצוניים. מהנדס מנוסה יכול לתכנן בלוק מותאם אישית כך שזמן העריכה יקטן ב-40% ושכפול קוד ייעלם. בפרויקט מסחר אלקטרוני אחד, החלפנו שלושה תוספים שונים בבלוק Feature Card יחיד—LCP ירד ב-300 אלפיות השנייה, TTFB השתפר ב-150 אלפיות השנייה, והתחזוקה הפכה לפשוטה יותר. אם אתם נתקלים בבעיות אלה, הזמינו פיתוח בלוקים מותאמים אישית ל-Concrete CMS ואנחנו נספק פתרון יעיל.
שלוש בעיות טיפוסיות שבלוק מותאם אישית פותר
- חוסר גמישות של בלוקים סטנדרטיים. לא ניתן להוסיף שדה אייקון או מתג פריסה לבלוק התוכן—רק דרך בלוק מותאם אישית. 2. שכפול קוד. אם אותה קבוצת שדות משמשת במספר עמודים, ללא בלוק מותאם אישית יש להעתיק HTML לכל עורך. 3. קאשינג. בלוקים סטנדרטיים שומרים במטמון כברירת מחדל, אבל עבור מבנים מורכבים צריך לכוונן את הקאשינג ידנית—בקונטרולר מותאם אישית זה לוקח כמה שורות.
כיצד אנו מפתחים בלוקים מותאמים אישית
אנו משתמשים בארכיטקטורה מוכחת לפי תבנית MVC: הקונטרולר (באמצעות הזרקת תלות דרך הקונטיינר של Concrete CMS) מטפל באימות ובשמירת נתונים, והתבנית מטפלת רק בפלט. לאחסון שדות אנו משתמשים ב-db.xml (סכמת Doctrine), ומנהלים קבצים באמצעות Concrete\Core\File\File. קחו לדוגמה את בלוק Feature Card לחנות מסחר אלקטרוני: 4 פריסות, אייקון ממנהל הקבצים, קאשינג פלט עם TTL של 3600 שניות.
מדריך שלב-אחר-שלב ליצירת בלוק
- צרו את מבנה התיקיות:
blocks/feature-card/עם קבציםcontroller.php,db.xml,add.php,edit.php,view.php,icon.png(48×48). עבור תבניות חלופיות, הוסיפו תיקייתtemplates/. - תארו את סכמת ה-DB ב-
db.xml: הגדירו שדות, סוגיהם ומפתחות. Concrete CMS יוצר את הטבלה אוטומטית בעת התקנת החבילה. - יישמו את הקונטרולר: הרחיבו את
BlockController, הגדירו מאפייני קאשינג וטבלה, דרסו את המתודותadd(),edit(),view(),save()ו-validate(). השתמשו ב-namespacing מסוג PSR-4. - צרו תבניות פלט:
view.phpלרנדור, תבניות חלופיות ב-templates/לפריסות שונות. - התקינו את הבלוק: דרך חבילה או ישירות ב-
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. לפיתוח בלוקים מעמיק יותר, ראו את התיעוד הרשמי.
כיצד להגדיר קאשינג לבלוק?
פרמטרי הקאשינג מוגדרים בקונטרולר. הגדרת blocks/feature-card/ controller.php # логика, валидация, CRUD db.xml # схема таблицы БД add.php # форма добавления блока edit.php # форма редактирования (обычно include add.php) view.php # шаблон вывода на странице icon.png # иконка (48×48) templates/ # альтернативные шаблоны вывода compact.php ו-<?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> ל-<?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; } } מאפשרת קאשינג של רשומות וקאשינג של פלט HTML. ה-TTL נשלט על ידי המאפיין <?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> . עבור בלוקים עם נתוני POST, יש להשבית קאשינג לאחר שליחה: btCacheBlockRecord. זה מונע הופעת תוכן מיושן לאחר עריכה. הגדרת קאשינג נכונה מפחיתה את TTFB ב-100–200 אלפיות השנייה.
בלוק עם מספר רשומות (רשימת פריטים)
עבור בלוקים מסוג רשימה, השתמשו ב-btCacheBlockOutput ובטבלת בת. בקונטרולר ציינו true. רשומות בת נשמרות במתודת save(): תחילה מחקו ישנות, לאחר מכן הכניסו חדשות עם מיון נכון.
דוגמה למבנה טבלת בת
<field name="sort" type="I">
<UNSIGNED/>
<DEFAULT value="0"/>
</field> לוחות זמנים לפיתוח בלוקים
| מורכבות | תיאור | לוח זמנים | הערכת עלות |
|---|---|---|---|
| פשוט | טקסט + תמונה + קישור | 4–8 שעות | $400–$800 |
| בינוני | רשימת פריטים, גלריה, טאבים | 1–2 ימים | $800–$1600 |
| מורכב | אינטגרציית API, JS מותאם אישית | 2–5 ימים | $1600–$4000 |
מה כלול בעבודה
- קונטרולר, תבניות (view + חלופיות), סכמת DB (db.xml).
- אימות שדות וטיפול מאובטח בנתונים.
- קאשינג פלט עם TTL אופטימלי.
- המרת נתונים קיימים (אם נדרש).
- תיעוד התקנה ושימוש.
- הדרכת עורכים על שימוש בבלוק.
- אחריות על קוד למשך 6 חודשים.
- חיסכון פוטנציאלי של עד $3000 בשנה על ידי ביטול מנויי תוספים.
האצת פיתוח עם תבניות חלופיות
השתמשו בתבניות חלופיות—הן מאפשרות לשנות את המראה ללא שינוי הלוגיקה. עבור סוגי בלוקים דומים (לדוגמה, וריאציות מרובות של כרטיסים), צרו קונטרולר אחד עם מתג פריסה בטופס העריכה. זה מקצר את זמן הפיתוח פי 2–3.
השוואה: בלוק מותאם אישית מול פתרונות מוכנים
| קריטריון | בלוק מותאם אישית | תוסף מוכן |
|---|---|---|
| גמישות | מלאה | מוגבלת להגדרות |
| ביצועים | מותאם למשימה | לעיתים כבד |
| תאימות לעדכונים | נשלטת | עלולה להישבר |
| זמן יישום | 4 שעות – 5 ימים | 1–2 ימים (אם מתאים) |
| עלות שנתית | חד-פעמית: $400–$4000 | $200–$600 לשנה מנוי |
בלוקים מותאמים אישית הם מהירים פי 3 מתוספים מוכנים במהירות הטעינה עם קאשינג נכון—LCP יורד ב-200–400 אלפיות השנייה. חיסכון בתקציב מביטול תוספים יכול להגיע עד 50%, שהם $2000 בשנה לעסק טיפוסי. הלקוחות שלנו חוסכים בממוצע $2,000 בשנה.
נעריך את הפרויקט שלכם תוך יום עסקים אחד. פשוט צרו קשר—נמצא את הפתרון הטוב ביותר לצרכים שלכם. תהליך פיתוח הבלוקים המותאמים אישית שלנו ל-Concrete CMS מבטיח אינטגרציה חלקה. כשאתם מזמינים בלוקים מותאמים אישית ל-Concrete CMS, אנו מטפלים בכל שלב מהקונטרולר ועד הקאשינג. עם ניסיון של 7+ שנים ומעל 50 פרויקטים שהושלמו, יש לנו את המומחיות לספק פתרונות באיכות גבוהה. לקוחות סומכים עלינו כבר 5+ שנים, ואנו מבטיחים שהבלוקים המותאמים אישית שלכם יהיו חזקים ובעלי ביצועים גבוהים. אם אתם זקוקים לפיתוח בלוקים מותאמים אישית ל-Concrete CMS, כולל יצירת בלוקים, תבניות, קאשינג, חבילות, קונטרולר ו-db.xml, הצוות שלנו יכול לעזור.
מדריך זה מכסה את כל ההיבטים של יצירת בלוקים מותאמים אישית ל-Concrete CMS באמצעות PSR-4 autoloading, הזרקת תלות ו-Doctrine ORM לסכמת מסד נתונים. פיתוח בלוקים נכון כולל הבנה של MVC, namespaces ומחלקות ניהול הקבצים של Concrete CMS. על ידי יישום עקרונות אלה, תוכלו ליצור בלוקים בעלי ביצועים טובים וקלים לתחזוקה.







