Custom ordering of ListBlock items?

334 views
Skip to first unread message

Matt

unread,
Jun 23, 2015, 11:11:49 AM6/23/15
to wag...@googlegroups.com
Is there a way to override the manual ordering of items in a StreamField ListBlock()?

I want to provide the user with a dropdown of ordering methods (manual, alphabetical, etc) which will change the order in which the list items are output in the template. However, I can't see an obvious way of doing this short of writing a rather hacky template tag.

Is there something similar to Django's 'ordering' model Meta attribute for Wagtail blocks?

Matthew Westcott

unread,
Jun 24, 2015, 5:03:36 AM6/24/15
to wag...@googlegroups.com
Hi Matt,
There's no built-in way of doing that - ListBlocks are only designed to return blocks in the order they're set up in the editor.

To avoid cramming in too much logic in the template, I'd suggest defining a custom 'render' method on the block:

from django.template.loader import render_to_string

class StaffListingBlock(blocks.StructBlock):
staff_members = blocks.ListBlock(StaffMemberBlock())
ordering = blocks.ChoiceBlock(choices=[('manual', 'Manual'), ('first_name', "First name"), ('surname', "Surname")])

def render(self, value):
if value['ordering'] == 'first_name':
staff_members = sorted(value['staff_members'], key=lambda member: member['first_name'])
elif value['ordering'] == 'surname':
staff_members = sorted(value['staff_members'], key=lambda member: member['surname'])
else:
staff_members = value['staff_members']

return render_to_string(self.meta.template, {
'self': value,
'staff_members': staff_members,
})
# the staff_listing.html template now has access to 'self' and the sorted 'staff_members' list

class Meta:
template = 'myapp/blocks/staff_listing.html'


Cheers,
- Matt

Matt

unread,
Jun 24, 2015, 6:40:26 AM6/24/15
to wag...@googlegroups.com
Thanks Matt, I didn't realise you could define a render() method on the block, that seems a better way of doing it than a template tag.
Reply all
Reply to author
Forward
0 new messages