wagtailwagtail-streamfield

Wagtail Streamblocks


I have the following Wagtail model body for a Page type:


     body = StreamField(
            [
                (
                    "main",
                    MainHeadingBlock(),
                ),
                (
                    "content",
                    blocks.StructBlock(
                        [
                            (
                                "sub",
                                SubHeadingBlock(
                                    label="Sub Heading",
                                ),
                            ),
                            (
                                "info",
                                blocks.StreamBlock(
                                    [
                                        (
                                            "content",
                                            ContentBlock(
                                                label="Content",
                                            ),
                                        ),
                                        (
                                            "label", 
                                            LabelBlock(
                                                label="Information Label",
                                            ),
                                        ),
                                        (
                                            "image",
                                            ImageChooserBlock(
                                                label="Supporting Image",
                                            ),
                                        ),
                                        (
                                            "calculator",
                                            CalculatorBlock(
                                                label="Calculators",
                                            ),
                                        ),
                                        (
                                            "flowchart",
                                            FlowchartBlock(
                                                label="Flowcharts",
                                            ),
                                        ),
                                    ]
                                ),
                            ),
                        ],
                        icon="cogs",
                    ),
                ),
            ],
            use_json_field=True,
        )

And am rendering out in a template as below:


    {% for block in page.body %}
                {% if block.block_type == 'main' %}
                    {% include 'blocks/mainheading.html' %}
                {% elif block.block_type == 'content' %}
                    <div class="content-block">
                    {% for item in block.value %}
                            {% if item == 'sub' %}
                                {% include 'blocks/subheading.html' %}
                            {% elif item == 'info' %}
                                {% for subblock in block.value.info %}
                                    {% include_block subblock %}
                                {% endfor %}
                            {% endif %}
                    {% endfor %}
                    </div>
                {% endif %}
            {% endfor %}

The blocks in the info Streamblock all have their own templates set via their individual models.

If I just build a page with the empty templates and don't try and access context, the markup appears as expected, but as soon as I use a 'label' block and try and access the block context via value, it seems to take all the following blocks in its section and render them as children, when I want them to be siblings - am I missing something fundamental here?

Label block included for reference:


    class LabelBlock(StructBlock):
        label = ChoiceBlock(
            choices=LABEL_CHOICES,
            default=LABEL_CHOICES[0],
            help_text="Please select the appropriate label",
            blank=False,
        )
        label_content = TextBlock(
            editor="default",
            help_text="Add some content for the label",
            blank=False,
        )
    
        class Meta:
            template = "blocks/label.html"
            icon = "duplicate"


Solution

  • Solved - was missing a closing div in a related template. That was fun.