Assume I am following the Your first Wagtail site tutorial, except I want to use a Streamfield, instead of separate RichTextField or BlogPageGalleryImage. For example :
class BlogPage(Page):
date = models.DateField("Post date")
intro = models.CharField(max_length=250)
body = RichTextField(blank=True)
... becomes ...
class BlogPage(Page):
body = StreamField([
('heading', blocks.CharBlock(classname="full title")),
('intro', blocks.RichTextBlock()),
('body', blocks.RichTextBlock()),
('image', ImageChooserBlock()),
], null=True, blank=True,)
How can I (or can I) pull the first image and the beginning of intro (...as I cannot restrict length) from a Streamfield for use in the blog_index_page.html template, and avoid using separate fields and BlogPageGalleryImage Class? Therefore replacing this template :
{% for post in blogpages %}
{% with post=post.specific %}
<h2><a href="{% pageurl post %}">{{ post.title }}</a></h2>
{% with post.main_image as main_image %}
{% if main_image %}{% image main_image fill-160x100 %}{% endif %}
{% endwith %}
<p>{{ post.intro }}<p>
{% endwith %}
{% endfor %}
With something more like this :
{% for post in blogpages %}
{% with post=post.specific %}
<h2><a href="{% pageurl post %}">{{ post.title }}</a></h2>
{{ post.body.image.first() }}
<p>{{ post.intro.get_words(50) }}</p>
{{ post.body|richtext }}
{% endwith %}
{% endfor %}
Many thanks.
I had the same exact question 5 years later, so hopefully it helps when somebody stumbles upon it. Solved it by making a method in BlogPage
class that checks if there are image blocks in the body (StreamField) and retuns the first image from the first image block.
def first_body_image(self):
image_blocks = [block for block in self.body if block.block_type == 'image']
if not image_blocks:
return None
return image_blocks[0].value
And you can use it in a template with image tags
{% image post.specific.first_body_image fill-300x300 %}