Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wagtail SnippetChooserBlock in Streamfield

I am having some trouble getting the values from a snippet, that I have included into a streamfield using a Snippet Chooser Block.

BioSnippet:

@register_snippet
class BioSnippet(models.Model):
    name = models.CharField(max_length=200, null=True)
    job_title = models.CharField(max_length=200, null=True, blank=True)
    bio = RichTextField(blank=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name='Bio Image'
    )
    contact_email = models.CharField(max_length=50, null=True, blank=True)
    contact_phone = models.CharField(max_length=50, null=True, blank=True)

    panels = [
        FieldPanel('name'),
        FieldPanel('job_title'),
        FieldPanel('bio'),
        ImageChooserPanel('image'),
        FieldPanel('contact_email'),
        FieldPanel('contact_phone'),
    ]

    def __str__(self):
        return self.name

    class Meta:
        ordering = ['name',]

Bio Streamfield Definitions:

class BioInline(StructBlock):
    bio = SnippetChooserBlock(BioSnippet)

class BioBlock(StructBlock):
    overall_title = CharBlock(required=False)
    bios = ListBlock(BioInline())

This all works, but when I get to the template, I cannot seem to access the values of the snippet

{% for b in child.value.bios %}
    {{ b }}

    <hr>
    {{ b.name }}

{% endfor %}

the {{ b }} tag outputs:

bio
Sales Team

However {{ b.name }} outputs nothing. Neither does {{ b.values.name }} or any other permutation I can guess at. I suspect the values are just not being pulled down.

like image 662
P.Sermon Avatar asked Oct 15 '25 07:10

P.Sermon


2 Answers

bios here is defined as a list of BioInline values, and so b in your template would be a BioInline value - which has a single property, bio (giving you the actual BioSnippet object). To get the name, you'd therefore have to use: {{ b.bio.name }}.

I don't think the BioInline object is actually gaining you anything though - you could instead define BioBlock as:

class BioBlock(StructBlock):
    overall_title = CharBlock(required=False)
    bios = ListBlock(SnippetChooserBlock(BioSnippet))

which would make bios a list of BioSnippets - {{ b.name }} would then work as expected.

like image 102
gasman Avatar answered Oct 16 '25 22:10

gasman


Alternatively, you can use self.bios

In blocks.py you have to import the Snippet model (should have this allready):

from thebioapp.models import BioSnippet

And then use this model in the template itself

{% for b in self.bios %}
    {{ b }}

    <hr>
    {{ b.name }}

{% endfor %}

The post is old, but as Wagtail is growing in popularity, I hope this will benefit others!

like image 39
moojen Avatar answered Oct 16 '25 21:10

moojen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!