wagtailwagtail-streamfieldwagtail-admin

How to specify nested blocks for StreamField default value?


I'm using Wagtail/CodeRedCMS to develop a site for a non-profit org. I have a custom EventPage class that inherits from CoderedEventPage. I would like to pre-populate new Event pages with a default set of nested blocks: Body->Responsive Grid Row->Column->Text. I have learned that this is possible by setting the default property on the StreamField object, and I have been able to use this successfully to pre-populate with a single child block. However, I can't figure out how to get it work for a nested structure.

I have gotten as far as the following within the EventPage class:

body = StreamField(
    LAYOUT_STREAMBLOCKS,
    null=True,
    blank=True,
    use_json_field=True,
    default=[
        ("row", {
            "content": [
                ("text", {"value":"foobar"})
            ]
        })
    ]
)

This doesn't throw an error like some of the other default values I tried, but it only half works.

What I expect/hope to see when adding a new Event page in the admin interface: new Event page with pre-populated body

What I see using the above code: new Event page with partially populated body

The Responsive Grid Row is pre-populated, which is partial success, but the column and text box are not. I understand that my default value is not quite right, but I can't seem to wrap my head around how to correctly specify it. Any help is appreciated.


Solution

  • You want to make the basic structure look something like this, but it seems this is a little problematic nevertheless.

    body = StreamField(
            LAYOUT_STREAMBLOCKS,
            null=True,
            blank=True,
            use_json_field=True,
            default=[
                ("row", {
                    "content": [
                        ("content", {"content": [("text", "Foobar")]})
                    ]
                })
            ]
        )
    

    In particular, you need to consider the GridBlock, ColumnBlock and each of the Streamblocks inside them.

    Also, it seems that the stream blocks need the stream child defaults in the format {"type": "...", "value": "..."}

    body = StreamField(
            LAYOUT_STREAMBLOCKS,
            null=True,
            blank=True,
            use_json_field=True,
            default=[
                {
                    "type": "row",
                    "value": {
                        "content": [
                            {
                                "type": "content",
                                "value": {
                                    "column_size": "",
                                    "content": [
                                        {
                                            "type": "text",
                                            "value": "Foobar"
                                        }
                                    ],
                                }
                            }
                        ],
                    }
                }
            ]
        )