wagtailwagtail-snippet

Why is the SnippetChooserPanel not opening in Wagtail?


Some time ago I stopped using @register_snippet to decorate Snippets. This takes the Snippet out of the snippets section of admin. Instead I used the wagtail_hooks.py to show the snippet directly in the left admin panel for user convenience. See below. This works nicely as the user can go directly to the snippet and you can also alter the displayed fields and ordering of fields - nice.

So in the below example I removed the line that says @register_snippet. What's the catch? The SnippetChooserPanel does not work! Later I was building a complex model and the SnippetChooserPanel did not work. I wasted quite a bit of time thinking the problem was in the complexity of my model. I want to save others' time!

wagtail_hooks.py:

from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
from wagtail.wagtailsnippets.models import register_snippet
from demo.models import Advert

class AdvertAdmin(ModelAdmin):
    model = Advert

modeladmin_register(AdvertAdmin)

Here is the snippet example from Wagtail: snippets

@register_snippet #<------- Source of issue (I removed this line!)

@python_2_unicode_compatible  # provide equivalent __unicode__ and __str__ methods on Python 2
class Advert(models.Model):
    url = models.URLField(null=True, blank=True)
    text = models.CharField(max_length=255)

    panels = [
        FieldPanel('url'),
        FieldPanel('text'),
    ]

    def __str__(self):
        return self.text

class BookPage(Page):
    advert = models.ForeignKey(
        'demo.Advert',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )

    content_panels = Page.content_panels + [
        SnippetChooserPanel('advert'),
        # ...
    ]

Solution

  • If you make your Snippets editable via modelAdmin you still need to apply the decorator @register_snippet. Otherwise the chooser panel route/view won't be available. This view is requested by the ajax request fired on SnippetChooser modal open. Missing @register snippet will trow a 404.

    You can register menu items via construct_main_menu hook. You can use the same hook to remove exiting menu-items. If you do not want the 'Snippets' menu item remove it. In wagtail_hooks.py:

    @hooks.register('construct_main_menu')
    def hide_snippet(request, menu_items):
        menu_items[:] = [item for item in menu_items if item.name != 'snippets']