I have created a custom GalleryBlock (StructBlock) for use in a StreamField. It contains a StreamBlock that allows selecting images via the ImageChooserBlock. In the template, I can iterate over the gallery images, but cannot use the {% image %} tag to resize them. I can display the images, but only the original size, which is available in the template as a prerendered img tag. I have been pouring over the code and have not been able to figure out a way to access the underlying image model in the template.
class GalleryBlock(blocks.StructBlock):
title = blocks.CharBlock(required=False)
description = blocks.CharBlock(required=False)
images = blocks.StreamBlock([
('image', ImageChooserBlock()),
])
class Meta:
icon = 'image'
template = 'blocks/gallery.html'
{% load wagtailimages_tags %}
<div class="gallery">
{% if self.title %}
<h4>{{ self.title }}</h4>
{% endif %}
{% for gallery_image in self.images %}
{# This will print a img tag with the original image size #}
{{ gallery_image }}
{# This fails with 'get_rendition' error #}
{% image gallery_image fill-850x400 as img %}
<img src="{{ img.url }}" class="thumbnail img-responsive" />
{% endfor %}
</div>
Hi @michaelfillier,
When you iterate over a StreamBlock value (as in {% for gallery_image in self.images %}), the items returned are actually wrapper objects of type StreamValue (source). This is necessary so that you can find out what kind of block each item is using (when multiple block types are in use - obviously, in this case there's only one). To retrieve the block's actual value, you need to access the .value property:
{% image gallery_image.value fill-850x400 as img %}
Alternatively, rather than using a StreamBlock with only one block type, you might consider using a ListBlock instead:
images = blocks.ListBlock(ImageChooserBlock())
That way, {% for gallery_image in self.images %} will iterate over the image models as expected.
Thank you so much! That is a much better solution than what I had. Really loving Wagtail.
Most helpful comment
Hi @michaelfillier,
When you iterate over a StreamBlock value (as in
{% for gallery_image in self.images %}), the items returned are actually wrapper objects of typeStreamValue(source). This is necessary so that you can find out what kind of block each item is using (when multiple block types are in use - obviously, in this case there's only one). To retrieve the block's actual value, you need to access the.valueproperty:Alternatively, rather than using a StreamBlock with only one block type, you might consider using a ListBlock instead:
That way,
{% for gallery_image in self.images %}will iterate over the image models as expected.