Marketing sites live and die by iteration speed. A page builder gives editors speed but fights developers; hand-rolled templates give developers control but bottleneck editors. StreamField sits in the middle.
Sections, not pages
Each section of a landing page is a StructBlock with its own Django template. Editors compose and reorder sections; developers own the templates. Nobody needs a drag-drop page builder.
The result is composition superpowers without the complexity: hero, stats, features, testimonials, pricing, FAQ — each a block, each rendered server-side, each editable in the Wagtail admin.
Why it scales
Blocks are plain Python classes with plain Django templates. New sections ship in a day, and the API serializer and server renderer pick them up automatically from the same field list.
Real StreamField blocks from Loop
A Hero block — the simplest section that starts every page document:
from wagtail import blocks
class HeroBlock(blocks.StructBlock):
badge = blocks.CharBlock(max_length=80, required=False)
title = blocks.CharBlock(max_length=200)
accent = blocks.CharBlock(max_length=60, required=False)
subtitle = blocks.TextBlock(required=False)
primary_cta = ButtonBlock(required=False)
secondary_cta = ButtonBlock(required=False)
class Meta:
template = 'content/blocks/hero.html'
label = 'Hero'
A course page — content-driven with a curriculum StreamField:
class CoursePage(Page):
title = models.CharField(max_length=255)
description = RichTextField(blank=True)
price_cents = models.IntegerField(default=0)
curriculum = StreamField([
('lesson', LessonBlock()),
('quiz', QuizBlock()),
], use_json_field=True)
content_panels = Page.content_panels + [
FieldPanel('description'),
FieldPanel('price_cents'),
FieldPanel('curriculum'),
]
These blocks ship from one codebase and render on both Django and Astro — the API auto-exposes every field from the same block list.
Comments
Sign in to join the conversation.
Commenting as