Tutorial Summary

This is part 2, coming from the previous article/video. In this lesson we'll be using a SnippetChooserPanel to select Blog Authors (a snippet we registered last episode). We'll also add in an Orderable to our Blog Detail Page so we can select between 1 and 4 Blog Authors.

This is part 2 about registering Snippets and using them in a SnippetChooserPanel. If you didn't catch the first video, you can find it here.

In this video we take an existing Snippet and let the user select the Snippet from the Wagtail Admin. But we take this a step further and allow the user to select between one and four Blog Authors by using a Orderable (more on Orderables here).

The entire process goes like this:

  1. Create a Django Model
  2. Register the model as a Wagtail Snippet
  3. Create an Orderable with a ForeignKey to the Django Model
  4. Create a SnippetChooserPanel that links to the ForeignKey
  5. On your page add an InlinePanel that links to your Orderable's related_name.

That's just about all there is to it. The code can be kind of confusing if this is your first time, so please take a look at the Git Commit or the chunk of code below.

# blog.models.py 
"""Blog listing and blog detail pages."""
from django.db import models

from modelcluster.fields import ParentalKey
from wagtail.admin.edit_handlers import (
from wagtail.snippets.edit_handlers import SnippetChooserPanel
from wagtail.core.models import Page, Orderable
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.snippets.models import register_snippet

class BlogAuthorsOrderable(Orderable):
    """This allows us to select one or more blog authors from Snippets."""

    page = ParentalKey("blog.BlogDetailPage", related_name="blog_authors")
    author = models.ForeignKey(

    panels = [
    	# Use a SnippetChooserPanel because blog.BlogAuthor is registered as a snippet

class BlogAuthor(models.Model):
    """Blog author for snippets."""

    name = models.CharField(max_length=100)
    website = models.URLField(blank=True, null=True)
    image = models.ForeignKey(

    panels = [
                # Use an ImageChooserPanel because wagtailimages.Image (image property) 
                # is a ForeignKey to an Image
            heading="Name and Image",

    def __str__(self):
        """String repr of this class."""
        return self.name

    class Meta:  # noqa
        verbose_name = "Blog Author"
        verbose_name_plural = "Blog Authors"

class BlogDetailPage(Page):
    """Blog detail page."""

   # ...

    content_panels = Page.content_panels + [
    	# ...
                InlinePanel("blog_authors", label="Author", min_num=1, max_num=4)
        # ...
{# blog_detail_page.html code snippet #}

{# Loop through all blog authors #}
{% for iter in self.blog_authors.all %}
    {% image iter.author.image fill-50x50 as img %}
        <img src="{{ img.url }}" class="rounded-circle" alt="{{ iter.author.name }}">
    {% if iter.author.website %}
        {# If there's a website, create an <a> tag
        <a href="{{ iter.author.website }}">
            {{ iter.author.name }}
    {% else %}
        {# No website; no <a> tag #}
        {{ iter.author.name }}
    {% endif %}
{% endfor %}
Sign up for our newsletter

Get notified about new lessons :)

Our Sites