Files
wagtailcms/apps/core/blocks.py
T
Zhengen 12f7caa158 feat: add products/cases page models and forms lead-capture app
- apps/products: ProductIndexPage/ProductPage
- apps/cases: CaseStudyIndexPage/CaseStudyPage
- apps/forms: FormDefinition/FormDefinitionField/Lead + submit API
- core/blocks: CaseStudyBlock, FormBlock (with API representation)
- register new apps, custom leads API route, migrations
2026-08-06 16:04:21 +08:00

165 lines
5.2 KiB
Python

"""
可复用的 StreamField Block 库。
参见 documents/设计方案分析与完善版.md §2.6 组件清单。
"""
from django.utils.translation import gettext_lazy as _
from wagtail import blocks
from wagtail.images.blocks import ImageChooserBlock
from wagtail.snippets.blocks import SnippetChooserBlock
class CTAButtonBlock(blocks.StructBlock):
text = blocks.CharBlock(max_length=50, label=_("按钮文案"))
link = blocks.URLBlock(label=_("按钮链接"))
class Meta:
icon = "link"
label = _("按钮")
class HeroBlock(blocks.StructBlock):
title = blocks.CharBlock(max_length=120, label=_("标题"))
subtitle = blocks.TextBlock(required=False, label=_("副标题"))
background_image = ImageChooserBlock(required=False, label=_("背景图"))
buttons = blocks.ListBlock(CTAButtonBlock(), label=_("按钮组"))
class Meta:
icon = "image"
label = _("首屏 Hero")
template = "core/blocks/hero_block.html"
class StatItemBlock(blocks.StructBlock):
value = blocks.CharBlock(max_length=20, label=_("数值"))
label = blocks.CharBlock(max_length=50, label=_("说明文字"))
class StatsBlock(blocks.StructBlock):
items = blocks.ListBlock(StatItemBlock(), label=_("数据项"))
class Meta:
icon = "site"
label = _("数据展示")
template = "core/blocks/stats_block.html"
class FeatureBlock(blocks.StructBlock):
icon = blocks.CharBlock(max_length=50, required=False, label=_("图标"))
title = blocks.CharBlock(max_length=100, label=_("标题"))
description = blocks.TextBlock(label=_("描述"))
class Meta:
icon = "pick"
label = _("能力/优势")
template = "core/blocks/feature_block.html"
class FeatureGridBlock(blocks.StructBlock):
heading = blocks.CharBlock(max_length=100, required=False, label=_("模块标题"))
items = blocks.ListBlock(FeatureBlock(), label=_("能力列表"))
class Meta:
icon = "grip"
label = _("能力网格")
class FAQItemBlock(blocks.StructBlock):
question = blocks.CharBlock(max_length=200, label=_("问题"))
answer = blocks.RichTextBlock(label=_("回答"))
class FAQBlock(blocks.StructBlock):
items = blocks.ListBlock(FAQItemBlock(), label=_("问答列表"))
class Meta:
icon = "help"
label = _("常见问题")
template = "core/blocks/faq_block.html"
class CTABlock(blocks.StructBlock):
heading = blocks.CharBlock(max_length=120, label=_("标题"))
description = blocks.TextBlock(required=False, label=_("描述"))
button = CTAButtonBlock(label=_("按钮"))
class Meta:
icon = "plus"
label = _("行动号召 CTA")
template = "core/blocks/cta_block.html"
class LogoCloudBlock(blocks.StructBlock):
heading = blocks.CharBlock(max_length=100, required=False, label=_("标题"))
logos = blocks.ListBlock(ImageChooserBlock(), label=_("Logo 列表"))
class Meta:
icon = "image"
label = _("客户 Logo 墙")
template = "core/blocks/logo_cloud_block.html"
class CaseStudyBlock(blocks.StructBlock):
case_page = blocks.PageChooserBlock(
page_type="cases.CaseStudyPage", label=_("案例页面")
)
summary = blocks.CharBlock(max_length=250, required=False, label=_("摘要覆盖"))
class Meta:
icon = "doc-full"
label = _("客户案例卡片")
class FormBlock(blocks.StructBlock):
"""嵌入可复用的线索表单(apps.forms.FormDefinition Snippet)。"""
form = SnippetChooserBlock("forms.FormDefinition", label=_("选择表单"))
class Meta:
icon = "form"
label = _("线索表单")
def get_api_representation(self, value, context=None):
"""
默认 SnippetChooserBlock 只会序列化为主键,前端渲染动态表单需要完整字段定义,
因此这里手动展开 FormDefinition 及其子字段(详见 apps/forms/models.py)。
"""
form_def = value.get("form")
if form_def is None:
return {"form": None}
return {
"form": {
"id": form_def.pk,
"name": form_def.name,
"submit_button_text": form_def.submit_button_text,
"success_message": form_def.success_message,
"fields": [
{
"label": field.label,
"field_key": field.field_key,
"field_type": field.field_type,
"required": field.required,
"choices": [
choice.strip()
for choice in field.choices.split(",")
if choice.strip()
],
}
for field in form_def.fields.all()
],
}
}
COMMON_BLOCKS = [
("hero", HeroBlock()),
("stats", StatsBlock()),
("feature_grid", FeatureGridBlock()),
("faq", FAQBlock()),
("cta", CTABlock()),
("logo_cloud", LogoCloudBlock()),
("case_study", CaseStudyBlock()),
("form", FormBlock()),
("richtext", blocks.RichTextBlock(label=_("富文本"))),
]