How to override StreamField ListBlock Template rendering

1,928 views
Skip to first unread message

Arthur Hanson

unread,
Jun 23, 2015, 2:08:42 AM6/23/15
to wag...@googlegroups.com
I use a ListBlock for a custom streamfield block type as I only need one type of element and want the user to be able to dynamically add more then one of them. However, I don't want to render it as <ul><li> elements.  I can specify the template, but what do I put in the template to render the list items?  So I make a class like:

class CustomlGroupBlock(blocks.StructBlock):
    items = blocks.ListBlock(MyCustomBlock(label="CustomBlock", template="myapp/customlistblock.html"))

Then in the template file I've unsuccessfully tried things like:

{{ self.render }} and {{ self.body }} and 

{% for block in self.bound_blocks %}
{{ block.render }}
{% endfor %}

Without specifying in the template the custom blocks render fine, but wrapped in <li> elements.  I need to get rid of the <ul> and <li> tags and be able to specify what wrapping html to use.  In the template for CustomGroupBlock I'm using:

  {{ self.bound_blocks.items.render }}

Would it be better in the template for CustomGroupBlock to iterate over items and not call render on the listblock?


Matthew Westcott

unread,
Jun 23, 2015, 5:15:30 AM6/23/15
to wag...@googlegroups.com
Hi Arthur,

items = blocks.ListBlock(MyCustomBlock(label="CustomBlock", template="myapp/customlistblock.html"))

In this line you have the template associated with MyCustomBlock rather than the ListBlock, so it will be called once per child, passing the MyCustomBlock instance as 'self', while the overall ListBlock still has the default <ul><li> rendering. You probably want the following:

items = blocks.ListBlock(MyCustomBlock(label="CustomBlock"), template="myapp/customlistblock.html")

You can then write the template as follows:
{% for block in self %}
{{ block }}
{% endfor %}


Cheers,
- Matt

Arthur Hanson

unread,
Jun 23, 2015, 5:35:14 AM6/23/15
to wag...@googlegroups.com
Doh!  Very obvious, I must be getting tired.  Thanks for the pointer to the mistake.

Niels Siemons

unread,
Feb 19, 2016, 8:58:56 AM2/19/16
to Wagtail support
Great,

I am new too wagtail,made the same mistake.

But it still generates a div: <div class="block-list">
Is there a possibly to remove it?

Generated output:

<div class="row">
<div class="block-list">
<div class="col-sm-4">..</>
<div class="col-sm-4">..</>
<div class="col-sm-4">..</>
</div>
</div>

Desirable output:
<div class="row">
<div class="col-sm-4">..</>
<div class="col-sm-4">..</>
<div class="col-sm-4">..</>
</div>


Thanks,
Niels

Matthew Westcott

unread,
Feb 19, 2016, 9:58:08 AM2/19/16
to wag...@googlegroups.com
Hi Niels,

The <div class="block-list"> tag comes from the default rendering for the stream as a whole. If you want a different rendering, you can loop over the blocks yourself - i.e. instead of:

<div class="row">
{{ page.body }}
</div>

use:

<div class="row">
{% for block in page.body %}
{{ block }}
{% endfor %}
</div>


Cheers,
- Matt

Niels Siemons

unread,
Feb 19, 2016, 11:10:30 AM2/19/16
to wag...@googlegroups.com
Hi Matt,

Great stuff. Works like a charme.

Niels


-- 
You received this message because you are subscribed to a topic in the Google Groups "Wagtail support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/wagtail/6ie8Wnk9mfs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to wagtail+u...@googlegroups.com.
To post to this group, send an email to wag...@googlegroups.com.
Visit this group at https://groups.google.com/group/wagtail.
To view this discussion on the web, visit https://groups.google.com/d/msgid/wagtail/8A9D5B2D-CBE2-4111-A26E-9FB9EECD480D%40torchbox.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages