0

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.

user3170530
  • 416
  • 3
  • 13
  • I don't know what you mean by "handling links programmatically (as opposed to as an editor)" - I suggest you open that as a separate question, giving full details of what you'd like to do. – gasman Aug 27 '21 at 00:43

1 Answers1

0

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 %}
gasman
  • 23,691
  • 1
  • 38
  • 56
  • Thank you for your response. To be honest, I didn't want to write code for this at all. I just wanted to handle what I thought was the very common case of having an image that is a hyperlink. There didn't seem to be any default way to do that which was very surprising to me. I expected Wagtail to have something to do that right out of the box. You can insert an embed into a RichTextField, you can insert an image, or you can insert a link but not an image that's also a link. – user3170530 Aug 27 '21 at 00:59