← Zurück zum Blog
WagtailStreamField22. Mai 2026· 12 min Lesezeit

Wagtail StreamField erweitern: eigene Blocks nachrüsten

Inhalt
  1. Warum eigene Blocks?
  2. StructBlock: der Arbeitspferd-Baustein
  3. Block-Templates & Kontext
  4. Validierung eigener Blocks
  5. Wiederverwendbare Block-Bibliothek
  6. Fazit

Die meisten Wagtail-Erweiterungen, die ich für Kunden baue, sind neue StreamField-Blöcke — ein Call-to-Action, eine Bildergalerie, ein Preistabellen-Block. Hier die Muster, die sich bewährt haben.

Warum eigene Blocks?

Redakteure sollen Inhalte zusammenstellen können, ohne HTML anzufassen — und ohne Dinge kaputt machen zu können. Ein gut gebauter Block ist selbsterklärend, validiert Eingaben und rendert konsistent.

StructBlock: der Arbeitspferd-Baustein

from wagtail import blocks
from wagtail.images.blocks import ImageChooserBlock

class CallToActionBlock(blocks.StructBlock):
    heading = blocks.CharBlock(required=True, max_length=80, label="Überschrift")
    text = blocks.TextBlock(required=False, label="Text")
    button_text = blocks.CharBlock(required=True, max_length=40)
    button_url = blocks.URLBlock(required=True)
    image = ImageChooserBlock(required=False)

    class Meta:
        icon = "pick"
        label = "Call to Action"
        template = "blocks/cta_block.html"
        help_text = "Ein Hinweisblock mit Button."

Diesen Block in ein bestehendes StreamField aufzunehmen ist unkompliziert — danach eine Migration erzeugen:

class BlogPage(Page):
    body = StreamField([
        ("paragraph", blocks.RichTextBlock()),
        ("cta", CallToActionBlock()),   # neuer Block
    ], use_json_field=True)

# python manage.py makemigrations && migrate

Block-Templates & Kontext

{# blocks/cta_block.html #}
{% load wagtailcore_tags wagtailimages_tags %}
{% if value.image %} {% image value.image width-400 %} {% endif %}

{{ value.heading }}

{% if value.text %}

{{ value.text }}

{% endif %} {{ value.button_text }}

Brauchst du zusätzlichen Kontext im Template, überschreibe get_context:

class LatestPostsBlock(blocks.StructBlock):
    count = blocks.IntegerBlock(default=3, min_value=1, max_value=10)

    def get_context(self, value, parent_context=None):
        ctx = super().get_context(value, parent_context)
        from blog.models import BlogPage
        ctx["posts"] = BlogPage.objects.live().order_by("-first_published_at")[:value["count"]]
        return ctx

    class Meta:
        template = "blocks/latest_posts.html"

Validierung eigener Blocks

Blöcke können ihre Eingaben validieren — wichtig, damit Redakteure sinnvolle Fehlermeldungen bekommen statt kaputter Seiten:

from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _

class CTABlock(blocks.StructBlock):
    button_text = blocks.CharBlock(required=False)
    button_url = blocks.URLBlock(required=False)

    def clean(self, value):
        result = super().clean(value)
        # Button-Text und URL nur gemeinsam sinnvoll
        if result["button_text"] and not result["button_url"]:
            raise ValidationError(_("Button-Text ohne URL angegeben."))
        return result

Wiederverwendbare Block-Bibliothek

In größeren Projekten lohnt sich eine zentrale blocks.py, aus der alle Seitentypen schöpfen. So bleiben Blöcke konsistent und Wartung zentral:

# common/blocks.py
class BodyStreamBlock(blocks.StreamBlock):
    paragraph = blocks.RichTextBlock()
    heading = blocks.CharBlock(form_classname="title")
    cta = CallToActionBlock()
    image = ImageChooserBlock()

    class Meta:
        block_counts = {"cta": {"max_num": 3}}  # Grenzen setzen

# In den Seiten:
body = StreamField(BodyStreamBlock(), use_json_field=True)

Fazit

Gute StreamField-Blöcke sind das Herz einer wartbaren Wagtail-Site: StructBlock für Struktur, saubere Templates, Validierung für Redakteurssicherheit und eine zentrale Bibliothek für Konsistenz. Genau hier entscheidet sich, ob Redakteure gern mit der Site arbeiten.

Yevhen Chubchyk
Yevhen Chubchyk
Senior Python / Django Entwickler · Freelancer seit 2016 · 20+ Jahre IT-Erfahrung. Wagtail-Projekte für Kunden im DACH-Raum.