פיתוח תבנית Sulu מותאמת אישית
לקוח פנה אלינו לאחרונה עם משימה: דף שירות צריך להכיל בלוקים עבור "טקסט", "תמונה+טקסט", "קריאה לפעולה", וסרגל צד עם טופס משוב. התבניות הסטנדרטיות של Sulu לא הציעו את השילוב הזה—הם היו צריכים לפרוץ את ממשק הניהול או ליצור תבנית מותאמת אישית. בנינו את הפתרון תוך יומיים: סכמת XML עם סוגי הבלוקים הנדרשים, תבנית Twig לעיבוד, ובקר מותאם אישית לטעינת המלצות. כעת המנהל יכול להרכיב את הדף מבלוקים מוכנים תוך דקות. לצוות שלנו יש ניסיון של 5+ שנים עם Sulu CMS והוא סיפק 20+ פרויקטים, תוך הבטחת פלט ללא באגים ועומד בדרישות. גמישות זו מאפשרת ללקוחותינו לחסוך עד 30% מתקציבי התחזוקה על ידי ביטול פריצות. בעת פיתוח 5–8 תבניות מותאמות אישית לאתר תאגידי, החיסכון יכול להגיע ל-40% בהשוואה לרכישת פתרון מוכן.
למה תבנית Sulu מותאמת אישית עדיפה על תבנית סטנדרטית
תבניות סטנדרטיות מכסות צרכים בסיסיים. אבל עבור דפים ייחודיים, לעתים קרובות אתה צריך שדות שאינם בקופסה. תבנית מותאמת אישית מאפשרת:
- הוספת כל סוגי השדות: עורכי טקסט, מדיה, בלוקים עם מבנה שרירותי.
- יצירת מספר פריסות עבור אותו סוג דף.
- חיבור בקר מותאם אישית לטעינת נתונים נוספים (למשל, רשומות קשורות או המלצות).
- שליטה בתצוגה דרך תבניות Twig ללא מגבלות.
התוצאה היא גמישות בלתי אפשרית עם פתרונות סטנדרטיים, עם הפחתת עלויות תחזוקה של 30–50% הודות לביטול עקיפות. לפי תיעוד Sulu, בקרים מותאמים אישית חוסכים זמן באינטגרציות.
איך לפתח תבנית Sulu מותאמת אישית
התהליך כולל מספר שלבים:
- ניתוח דרישות הדף והסכמה על המבנה.
- עיצוב סכמת XML עם שדות ובלוקים.
- פיתוח תבנית Twig תוך התחשבות בעיצוב.
- כתיבת בקר מותאם אישית (אם יש צורך בנתונים נוספים).
- אינטגרציה עם הערכת הנוכחית ובדיקות.
- פריסה לשרת ובדיקה סופית.
- מתן תיעוד והדרכה.
לוחות הזמנים תלויים במורכבות. להלן משכים משוערים עבור סוגי תבניות שונים.
| סוג תבנית | בלוקים ייחודיים | זמן פיתוח |
|---|---|---|
| פשוטה (טקסט, מדיה) | 2–4 | 1–2 ימים |
| בינונית (עורך בלוקים, שדות מותאמים) | 5–8 | 2–3 ימים |
| מורכבת (בקר מותאם אישית, אינטגרציות) | 8+ | 3–5 ימים |
השוואה בין תבנית סטנדרטית למותאמת אישית
| קריטריון | תבנית סטנדרטית | תבנית מותאמת אישית |
|---|---|---|
| מספר שדות | מוגבל | בלתי מוגבל |
| סוגי בלוקים | רק טקסט | טקסט, מדיה, CTA, גלריה וכו' |
| בקר | רק DefaultController | מותאם אישית עם כל לוגיקה |
| גמישות | נמוכה | גבוהה |
דוגמת תבנית XML
<template xmlns="http://schemas.sulu.io/template/template" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/template-1.0.xsd">
<key>service</key>
<view>pages/service</view>
<controller>App\Controller\Website\ServiceController::indexAction</controller>
<cacheLifetime type="seconds">1800</cacheLifetime>
<properties>
<property name="title" type="text_line" mandatory="true">
<meta><title lang="ru">Заголовок</title></meta>
<tag name="sulu.rlp.part"/>
</property>
<property name="intro" type="text_area" colspan="12">
<meta><title lang="ru">Вступительный текст</title></meta>
<params>
<param name="rows" value="3"/>
</params>
</property>
<block name="content_blocks" default-type="text" colspan="12">
<meta><title lang="ru">Блоки контента</title></meta>
<types>
<type name="text">
<meta><title lang="ru">Текст</title></meta>
<properties>
<property name="text" type="text_editor">
<meta><title lang="ru">Текст</title></meta>
</property>
</properties>
</type>
<type name="image_text">
<meta><title lang="ru">Изображение + текст</title></meta>
<properties>
<property name="image" type="single_media_selection">
<meta><title lang="ru">Изображение</title></meta>
</property>
<property name="text" type="text_editor">
<meta><title lang="ru">Текст</title></meta>
</property>
<property name="image_position" type="select">
<meta><title lang="ru">Позиция изображения</title></meta>
<params>
<param name="values" type="collection">
<param name="left" title="Слева"/>
<param name="right" title="Справа"/>
</param>
</params>
</property>
</properties>
</type>
<type name="cta">
<meta><title lang="ru">Призыв к действию</title></meta>
<properties>
<property name="heading" type="text_line">
<meta><title lang="ru">Заголовок</title></meta>
</property>
<property name="button_text" type="text_line">
<meta><title lang="ru">Текст кнопки</title></meta>
</property>
<property name="button_link" type="text_line">
<meta><title lang="ru">Ссылка</title></meta>
</property>
</properties>
</type>
</types>
</block>
<section name="sidebar">
<meta><title lang="ru">Боковая панель</title></meta>
<properties>
<property name="show_form" type="checkbox">
<meta><title lang="ru">Показать форму обратной связи</title></meta>
<params>
<param name="defaultValue" value="true"/>
</params>
</property>
<property name="related_services" type="smart_content">
<meta><title lang="ru">Похожие услуги</title></meta>
<params>
<param name="provider" value="pages"/>
<param name="types" value="service"/>
<param name="max_per_page" value="4"/>
</params>
</property>
</properties>
</section>
</properties>
</template> תבנית Twig
{% extends 'base.html.twig' %}
{% block title %}{{ content.title }} | {{ app.request.host }}{% endblock %}
{% block body %}
<div class="page-service">
<h1>{{ content.title }}</h1>
{% for block in content.content_blocks %}
<div class="block block--{{ block.type }}">
{% if block.type == 'text' %}
{{ block.text|raw }}
{% elseif block.type == 'image_text' %}
<img src="{{ sulu_resolve_media(block.image, locale).thumbnails['service-block'] }}" alt="" loading="lazy">
{{ block.text|raw }}
{% elseif block.type == 'cta' %}
<h2>{{ block.heading }}</h2>
<a href="{{ block.button_link }}" class="btn">{{ block.button_text }}</a>
{% endif %}
</div>
{% endfor %}
</div>
{% endblock %} בקר מותאם אישית
class ServiceController extends AbstractController
{
public function indexAction(StructureInterface $structure): Response
{
$testimonials = $this->testimonials->findByService($structure->getUuid(), limit: 3);
return $this->render('pages/service.html.twig', [
'content' => $structure->getContent(),
'testimonials' => $testimonials,
]);
}
} רישום התבנית ב-Webspace
<templates> <template type="page">service</template> </templates> לאחר הוספת התבנית, נקה את המטמון ובצע אינדוקס מחדש:
php bin/console cache:clear php bin/console sulu:document:initialize מלכודות נפוצות ופתרונות
- התבנית לא מיושמת — לרוב שוכחים לרשום את המפתח ב-webspace או לנקות את המטמון. תמיד בדוק את רשומת התצורה והרץ את
<template xmlns="http://schemas.sulu.io/template/template" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/template-1.0.xsd"> <key>service</key> <view>pages/service</view> <controller>App\Controller\Website\ServiceController::indexAction</controller> <cacheLifetime type="seconds">1800</cacheLifetime> <properties> <property name="title" type="text_line" mandatory="true"> <meta><title lang="ru">Заголовок</title></meta> <tag name="sulu.rlp.part"/> </property> <property name="intro" type="text_area" colspan="12"> <meta><title lang="ru">Вступительный текст</title></meta> <params> <param name="rows" value="3"/> </params> </property> <block name="content_blocks" default-type="text" colspan="12"> <meta><title lang="ru">Блоки контента</title></meta> <types> <type name="text"> <meta><title lang="ru">Текст</title></meta> <properties> <property name="text" type="text_editor"> <meta><title lang="ru">Текст</title></meta> </property> </properties> </type> <type name="image_text"> <meta><title lang="ru">Изображение + текст</title></meta> <properties> <property name="image" type="single_media_selection"> <meta><title lang="ru">Изображение</title></meta> </property> <property name="text" type="text_editor"> <meta><title lang="ru">Текст</title></meta> </property> <property name="image_position" type="select"> <meta><title lang="ru">Позиция изображения</title></meta> <params> <param name="values" type="collection"> <param name="left" title="Слева"/> <param name="right" title="Справа"/> </param> </params> </property> </properties> </type> <type name="cta"> <meta><title lang="ru">Призыв к действию</title></meta> <properties> <property name="heading" type="text_line"> <meta><title lang="ru">Заголовок</title></meta> </property> <property name="button_text" type="text_line"> <meta><title lang="ru">Текст кнопки</title></meta> </property> <property name="button_link" type="text_line"> <meta><title lang="ru">Ссылка</title></meta> </property> </properties> </type> </types> </block> <section name="sidebar"> <meta><title lang="ru">Боковая панель</title></meta> <properties> <property name="show_form" type="checkbox"> <meta><title lang="ru">Показать форму обратной связи</title></meta> <params> <param name="defaultValue" value="true"/> </params> </property> <property name="related_services" type="smart_content"> <meta><title lang="ru">Похожие услуги</title></meta> <params> <param name="provider" value="pages"/> <param name="types" value="service"/> <param name="max_per_page" value="4"/> </params> </property> </properties> </section> </properties> </template>. - הפניה שגויה לבקר — ציין את המחלקה והמתודה המלאים, אחרת Sulu לא ימצא את הבקר. השתמש ב-
{% extends 'base.html.twig' %} {% block title %}{{ content.title }} | {{ app.request.host }}{% endblock %} {% block body %} <div class="page-service"> <h1>{{ content.title }}</h1> {% for block in content.content_blocks %} <div class="block block--{{ block.type }}"> {% if block.type == 'text' %} {{ block.text|raw }} {% elseif block.type == 'image_text' %} <img src="{{ sulu_resolve_media(block.image, locale).thumbnails['service-block'] }}" alt="" loading="lazy"> {{ block.text|raw }} {% elseif block.type == 'cta' %} <h2>{{ block.heading }}</h2> <a href="{{ block.button_link }}" class="btn">{{ block.button_text }}</a> {% endif %} </div> {% endfor %} </div> {% endblock %}כדי לוודא. - בלוקים לא מוצגים — ודא שבתבנית Twig, לכל סוג בלוק יש לוגיקה מתאימה. טעות נפוצה היא חוסר בבדיקת
class ServiceController extends AbstractController { public function indexAction(StructureInterface $structure): Response { $testimonials = $this->testimonials->findByService($structure->getUuid(), limit: 3); return $this->render('pages/service.html.twig', [ 'content' => $structure->getContent(), 'testimonials' => $testimonials, ]); } }בלולאה.
מה כלול בעבודה
- סכמת XML עם שדות ובלוקים
- תבנית Twig עם פריסה רספונסיבית
- בקר מותאם אישית (אם נדרש)
- אינטגרציה עם CMS והגדרת הרשאות גישה
- תיעוד מבנה התבנית
- הדרכה למנהלי תוכן על עבודה עם בלוקים
- אחריות איכות ותמיכה לאחר הפריסה
אנו מספקים פריסת Sulu מותאמת אישית ופיתוח אתרי Sulu מלא. פתרונות תבנית Sulu המותאמים אישית שלנו עונים במלואם על הדרישות שלך וחוסכים בתקציב.
לוחות זמנים וכיצד להזמין
תבנית אחת עם עורך בלוקים, בקר מותאם אישית ו-Twig אורכת 2–3 ימים. סט מלא של תבניות (5–8 סוגים) לאתר תאגידי אורך 1.5–2 שבועות. העלות מחושבת באופן אישי לפי מורכבות והיקף.
צור קשר כדי לדון בפרויקט שלך—נכין הצעה מפורטת. קבל ייעוץ על פיתוח תבנית Sulu מותאמת אישית עוד היום.







