Skip to content

# Custom Content

For custom content that doesn't fit existing panels:

## Consider using `TextPanel` with custom formatting

views.py

    from nautobot.apps import views
    from nautobot.apps.ui import TextPanel

    class DeviceDetailView(views.NautobotUIViewSet):
        panels = [
            TextPanel(weight=100, context_field="custom_content"),
        ]

        def get_extra_context(self, request, instance):
            context = super().get_extra_context(request, instance)
            context["custom_content"] = "My Custom Content"
            return context

## Use `KeyValueTablePanel` with transformed data

views.py

    from nautobot.apps import views
    from nautobot.apps.ui import KeyValueTablePanel, ObjectDetailContent
    from nautobot.core.templatetags.helpers import (
        divide,
        placeholder,
        slugify,
        split,
    )

    class DeviceUIViewSet(views.NautobotUIViewSet):
        object_detail_content = ObjectDetailContent(
            panels=[
                KeyValueTablePanel(weight=100, value_transforms={
                    "name": [slugify, placeholder],
                    "list_of_names": split,
                    "number_value": lambda v: divide(v, 3),
                }),
            ]
        )

        def get_extra_context(self, request, instance):
            context = super().get_extra_context(request, instance)
            context["data"] = {
                "name": "Some Example Name",
                "list_of_names": "Name1 Name2 Name3",
                "number_value": 1000,
            }
            return context

More built-in filters can be found in `Nautobot Built-In Filters`

## Create a custom Panel class if needed

custom_panel.py

    from django.template.loader import get_template
    from nautobot.apps.ui import Panel

    class CustomPanel(Panel):

        # You can override default body panel
        def __init__(self, *, body_content_template_path="my_app/custom_panel/body_content.html", **kwargs):
            super().__init__(body_content_template_path=body_content_template_path, **kwargs)

        # Adding some extra context specially for this panel / or this custom template
        def get_extra_context(self, context):
            # This context will be passed to the label, header, body and footer render methods
            return {"custom_data": "I love Nautobot!"}

views.py

    from nautobot.apps import views
    from nautobot.apps.ui import ObjectDetailContent
    from device_app.custom_panel import CustomPanel

    class DeviceUIViewSet(views.NautobotUIViewSet):
        object_detail_content = ObjectDetailContent(
            panels=[
                CustomPanel(weight=100),
            ]
        )

Note

If more custom behaviour is needed, you can override other `Panel` rendering methods. For more details please refer to the `Panel` Code Reference.