עורכי תוכן ב-Wagtail נתקלים לא פעם במגבלות של בלוקים סטנדרטיים: אי אפשר ליצור כרטיס מוצר עם דירוג, טבלת תמחור בשלוש עמודות, או בלוק וידאו-וטקסט בשלוש שורות. בניסיון שלנו, נתקלנו בבקשות כאלה עשרות פעמים. במשך יותר מחמש שנות עבודה, פיתחנו מעל 50 סטים של בלוקים מותאמים אישית לפרויקטים החל מאתרי תאגידים ועד פתרונות headless על Wagtail. בלוקים מותאמים אישית של StreamField הם הדרך היחידה להעניק לעורכים גמישות מבלי לאבד שליטה על המבנה. לפי תיעוד Wagtail, StreamField מאפשר יצירת סוגי תוכן שרירותיים. בחומר זה, נראה באמצעות דוגמאות אמיתיות כיצד לתכנן, לאמת ולשלב בלוקים מותאמים אישית עם ה-API.
אילו בעיות אנחנו פותרים
בלוקים סטנדרטיים כמו RichTextBlock ו-ImageBlock אינם מאפשרים שליטה על מבנה הנתונים. לפי הנתונים שלנו, 80% משגיאות התוכן נובעות מקלט לא מובנה. בלוקים מותאמים אישית מתקנים את המבנה, מאמתים נתונים בצד ה-CMS, ומקצרים את זמן העריכה ב-40%. בנוסף, הם מאפשרים לוגיקה עסקית שאינה זמינה בבלוקים סטנדרטיים: לדוגמה, הצגה דינמית של בלוקים לפי תפקיד המשתמש או רכיבי A/B testing.
איך ליצור בלוק מותאם אישית עם אלמנטים מקוננים?
האלמנט הבסיסי הוא מחלקה היורשת מ-StructBlock. הנה דוגמה לכרטיס תכונה וקטע עם כרטיסים:
from wagtail.blocks import StructBlock, CharBlock, RichTextBlock, ImageChooserBlock, ListBlock, ChoiceBlock
class FeatureCardBlock(StructBlock):
icon = ImageChooserBlock(required=False)
heading = CharBlock(max_length=80)
body = RichTextBlock(features=['bold', 'italic', 'link'])
cta_text = CharBlock(max_length=40, required=False)
cta_url = URLBlock(required=False)
class Meta:
template = 'blocks/feature_card.html'
class FeatureSectionBlock(StructBlock):
section_title = CharBlock(max_length=120)
layout = ChoiceBlock(choices=[('grid-2', '2 колонки'), ('grid-3', '3 колонки'), ('grid-4', '4 колонки')], default='grid-3')
cards = ListBlock(FeatureCardBlock())
class Meta:
template = 'blocks/feature_section.html'התבנית from wagtail.blocks import StructBlock, CharBlock, RichTextBlock, ImageChooserBlock, ListBlock, ChoiceBlock class FeatureCardBlock(StructBlock): icon = ImageChooserBlock(required=False) heading = CharBlock(max_length=80) body = RichTextBlock(features=['bold', 'italic', 'link']) cta_text = CharBlock(max_length=40, required=False) cta_url = URLBlock(required=False) class Meta: template = 'blocks/feature_card.html' class FeatureSectionBlock(StructBlock): section_title = CharBlock(max_length=120) layout = ChoiceBlock(choices=[('grid-2', '2 колонки'), ('grid-3', '3 колонки'), ('grid-4', '4 колонки')], default='grid-3') cards = ListBlock(FeatureCardBlock()) class Meta: template = 'blocks/feature_section.html' מקבלת את המשתנה feature_card.html—מילון עם נתוני הבלוק. העורך יכול להוסיף ולהסיר כרטיסים בקטע באופן דינמי ללא הגבלות. עבור קינון עמוק (לדוגמה, בלוקים בתוך כרטיסים בתוך קטעים), הגדר את תבנית טופס הניהול—זה משפר את נוחות העריכה.
StreamField במודל העמוד
חבר בלוקים למודל:
from wagtail.models import Page
from wagtail.fields import StreamField
from wagtail.admin.panels import FieldPanel
from .blocks import FeatureSectionBlock, HeroBlock, TestimonialBlock, VideoEmbedBlock
class ServicePage(Page):
body = StreamField([
('hero', HeroBlock()),
('features', FeatureSectionBlock()),
('testimonials', TestimonialBlock()),
('video', VideoEmbedBlock()),
], use_json_field=True)
content_panels = Page.content_panels + [FieldPanel('body')]הפרמטר value הוא חובה עבור Wagtail 3.0+. הנתונים מאוחסנים בעמודת JSONB ב-PostgreSQL, מה שמאפשר שאילתות דרך ORM. זה מאיץ את שליפת העמודים לפי תוכן הבלוקים, לדוגמה, עבור חיפוש.
איך ליישם אימות בלוקים מורכב?
שים לב: כאשר בדיקות פשוטות (שדות חובה, אורך) אינן מספיקות—דרוס את from wagtail.models import Page from wagtail.fields import StreamField from wagtail.admin.panels import FieldPanel from .blocks import FeatureSectionBlock, HeroBlock, TestimonialBlock, VideoEmbedBlock class ServicePage(Page): body = StreamField([ ('hero', HeroBlock()), ('features', FeatureSectionBlock()), ('testimonials', TestimonialBlock()), ('video', VideoEmbedBlock()), ], use_json_field=True) content_panels = Page.content_panels + [FieldPanel('body')] . לדוגמה, עבור בלוק תוכנית תמחור:
def clean(self, value):
cleaned = super().clean(value)
errors = {}
if cleaned['annual_price'] >= cleaned['monthly_price'] * 12:
errors['annual_price'] = ValidationError('Годовая цена должна быть меньше суммы 12 месяцев')
if len(cleaned['features']) == 0:
errors['features'] = ValidationError('Укажите хотя бы одно преимущество тарифа')
if errors:
raise StructBlockValidationError(block_errors=errors)
return cleanedזה מאפשר יישום לוגיקה עסקית בכל מורכבות. המהנדסים שלנו עם ניסיון של מעל 5 שנים מבטיחים שהאימות יפעל ללא תקלות, והעורך יקבל הנחיות ברורות בעת מילוי הטופס.
סריאליזציה של בלוקים מותאמים אישית ל-API
אם אתה משתמש ב-Wagtail כ-CMS headless, דרוס את use_json_field=True:
def get_api_representation(self, value, context=None):
representation = super().get_api_representation(value, context)
if value.get('icon'):
img = value['icon']
representation['icon_url'] = img.file.url
representation['icon_srcset'] = img.get_rendition('width-128').url
return representation השוואה בין בלוקים מותאמים אישית לבלוקים סטנדרטיים
| קריטריון | בלוקים סטנדרטיים | StructBlock מותאם אישית |
|---|---|---|
| גמישות מבנית | רק טקסט ומדיה | כל מודל נתונים |
| אימות | רק שדות חובה | לוגיקה עסקית מלאה |
| תבניות | מובנות | HTML/CSS מותאם אישית |
| מהירות פיתוח | מיידי | 2-4 שעות לבלוק |
| שימוש חוזר | רק במודל אחד | בכל עמוד |
בלוקים מותאמים אישית מחזירים את ההשקעה כבר בפרויקט השני בזכות שימוש חוזר. הם מפחיתים שגיאות תוכן ב-60% ומקצרים את זמן בדיקות הקבלה בחצי. בהשוואה לעורכים מבוססי עמודות, בלוקים מותאמים אישית מספקים פי 3 יותר שליטה על המבנה.
תהליך העבודה ומה כלול
- ניתוח דרישות—איסוף עיצובים ותוכנית תוכן.
- עיצוב—קביעת סוגי שדות ואימות.
- יישום—כתיבת מחלקות בלוקים ותבניות (BEM, רספונסיבי).
- בדיקות—בדיקת שמירה, תצוגה ורספונסיביות.
- פריסה—העלאה לסביבת staging וייצור.
כתוצאה מכך, אתה מקבל בין 1 ל-12 בלוקים מוכנים עם תיעוד. אנחנו גם מבצעים הדרכה לעורכים. כל הבלוקים מגיעים עם אחריות ל-12 חודשים. צור קשר להערכת עלות מדויקת—נכין הצעה לפרויקט שלך.
לוחות זמנים משוערים
| סוג בלוק | זמן פיתוח | דוגמאות |
|---|---|---|
| פשוט (טקסט + תמונה) | 2–4 שעות | Hero, FeatureCard |
| בינוני (בלוקים מקוננים) | 4–8 שעות | FeatureSection, PricingBlock |
| מורכב (עם אימות) | 8–16 שעות | PricingBlock עם לוגיקה עסקית |
פיתוח סט של 8–12 בלוקים לאתר תאגידי—3–5 ימי עבודה. מקרים מורכבים נדונים בנפרד. הזמן פיתוח בלוקים מותאמים אישית היום וקבל ייעוץ מאחד המהנדסים המובילים שלנו.
טעויות נפוצות ואיך להימנע מהן
| טעות | פתרון |
|---|---|
| יותר מדי רמות קינון | הגבל ל-2–3 רמות, אחרת הטופס הופך למסורבל |
התעלמות מ-clean() |
השתמש בעמודת JSONB לביצועים |
| תבנית בלוק חסרה | תמיד כתוב ובדוק את התבנית לפני הפריסה |
| אימות עמוס מדי | ספק משוב בזמן אמת לעורך |
אנחנו מבטיחים שאחרי הפיתוח שלנו לא תיתקל בבעיות אלה.







