I'm sorry I have to ask this question because it seems so simple but I've been searching the documentation for hours looking for an answer. The scenario is:
I want to let editors embed images that are also hyperlinks so the image is clickable and will redirect to an external link. The documentation says use a StreamField. OK, I set up a model with a StreamField:
@register_snippet
class EventPageEntry(Orderable):
page = ParentalKey(EventPage, on_delete=models.CASCADE, related_name='event_entries')
heading = RichTextField(max_length=160)
body = StreamField([
('paragraph', blocks.RichTextBlock()),
('rich_image', blocks.StructBlock([
('image', ImageChooserBlock()),
('image_link', blocks.URLBlock())
]))
])
My template looks like this:
<div class="accordion-body">
{% for block in event_entry.body %}
{% if block.block_type == 'paragraph' %}
{{ block.value | richtext }}
{% endif %}
{% if block.block_type == 'rich_image' %}
{% image block.image fill-320x320 %}
<a href="{{ block.image_link }}">LINK TEXT</a>
{% endif %}
{% endfor %}
</div>
So here's what happens:
Paragraphs work fine. I can insert Rich Text blocks and they display exactly as expected.
When I add a rich_image, I see no image. In the anchor element, LINK TEXT appears, but hyperlinks to nothing (empty string).
I return to the wagtail editor and lo and behold the images and the link are there. Yes, I am saving the draft and publishing the page.
What is the correct way to do this? The wagtail editor looks fine, it lets me insert images and external URLS in the editor, they simply don't appear in the template.
Also, if there is some hidden part of the documentation I've missed on how to handle links programmatically (as opposed to as an editor) PLEASE PLEASE tell me I'm an idiot and link me to the page. I just can't find it.
As mentioned in the template rendering docs: When you loop over the blocks in a StreamField ({% for block in event_entry.body %}
), the block
objects you get back have two properties, block_type
and value
. This is true for all block types, including StructBlock - the only difference is the kind of value in the value
property. In the case of a StructBlock, value
is a dict containing the data of individual sub-blocks you've defined - so to output the data, you need to look in block.value
, not just block
.
{% if block.block_type == 'rich_image' %}
{% image block.value.image fill-320x320 %}
<a href="{{ block.value.image_link }}">LINK TEXT</a>
{% endif %}