Search code examples
wagtailwagtail-admin

Wagtail customization of admin template for Page Type Model


For example i have model like this and i want to add some button or image to the edit template of this page(Admin interface).I did not find a way how to do this using hooks.I think there must be some solution, otherwise it turns out that the pages(Admin interface of Page type model's) cannot be customized. If you have any solution or suggestions,I will be very grateful

class SomePage(Page):
    max_count = 1
    text = models.TextField(verbose_name='Text')
    content_panels = Page.content_panels + [
        FieldPanel("text"),
    ]

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        return context

enter image description here


Solution

  • You can achieve this with a custom Panel.

    Create a class that inherits wagtail.admin.panels.Panel, add any parameters you might want to the init then render whatever you want in Panel.BoundPanel.render_html(). You can load any extra needed js/css via insert_global_admin_js/insert_global_admin_css hooks. You need to pass any additional arguments into clone(), these values are accessible in the BoundPanel with self.panel.some_arg.

    Something like:

    class SomePanel(Panel):
        def __init__(self, something, *args, **kwargs):
            self.something = something
            super().__init__(*args, **kwargs)
    
        def clone(self):
            return self.__class__(
                something =self.something,
            )
    
        class BoundPanel(Panel.BoundPanel):
            def render_html(self, parent_context):
                return mark_safe(get_some_html(thing=self.panel.something))
    

    Then in your page/model:

    content_panels = Page.content_panels + [
        ....
        SomePanel(something='some_value')
    ]
    

    With this route, you're free to display whatever you want on the editor's interface. Could be a live feed to provide dynamic information, or a button to calculate a field on the page for example. Re-usable as well since you can put it into any model, not just the current.

    I have an example for customising FieldPanels on my site: https://enzedonline.com/en/tech-blog/import-text-file-into-a-textarea-html-form-field/

    The process for Panels is more or less the same for as for FieldPanels, only you don't have a field you're binding to and don't need to call the super.render_html() since you're starting from scratch with a Panel. Also, from my understanding, for custom arguments, you use clone with Panel and clone_kwargs with FieldPanel.