diff --git a/netbox/utilities/tables.py b/netbox/utilities/tables.py index 9000af110..82f25ebaf 100644 --- a/netbox/utilities/tables.py +++ b/netbox/utilities/tables.py @@ -216,18 +216,19 @@ class ButtonsColumn(tables.TemplateColumn): attrs = {'td': {'class': 'text-end text-nowrap noprint'}} # Note that braces are escaped to allow for string formatting prior to template rendering template_code = """ + {{% load helpers %}} {{% if "changelog" in buttons %}} - + {{% endif %}} {{% if "edit" in buttons and perms.{app_label}.change_{model_name} %}} - + {{% endif %}} {{% if "delete" in buttons and perms.{app_label}.delete_{model_name} %}} - + {{% endif %}} diff --git a/netbox/utilities/templatetags/helpers.py b/netbox/utilities/templatetags/helpers.py index 0e45cb581..be7dc97d1 100644 --- a/netbox/utilities/templatetags/helpers.py +++ b/netbox/utilities/templatetags/helpers.py @@ -16,9 +16,10 @@ from django.utils.safestring import mark_safe from markdown import markdown from netbox.config import get_config +from netbox.settings import PLUGINS from utilities.forms import get_selected_values, TableConfigForm from utilities.markdown import StrikethroughExtension -from utilities.utils import foreground_color +from utilities.utils import foreground_color, resolve_namespace register = template.Library() @@ -115,7 +116,8 @@ def viewname(model, action): """ Return the view name for the given model and action. Does not perform any validation. """ - return f'{model._meta.app_label}:{model._meta.model_name}_{action}' + namespace = resolve_namespace(model) + return f'{namespace}:{model._meta.model_name}_{action}' @register.filter() @@ -123,7 +125,8 @@ def validated_viewname(model, action): """ Return the view name for the given model and action if valid, or None if invalid. """ - viewname = f'{model._meta.app_label}:{model._meta.model_name}_{action}' + namespace = resolve_namespace(model) + viewname = f'{namespace}:{model._meta.model_name}_{action}' try: # Validate and return the view name. We don't return the actual URL yet because many of the templates # are written to pass a name to {% url %}. diff --git a/netbox/utilities/utils.py b/netbox/utilities/utils.py index 444b87523..bf2b1638c 100644 --- a/netbox/utilities/utils.py +++ b/netbox/utilities/utils.py @@ -13,10 +13,20 @@ from jinja2.sandbox import SandboxedEnvironment from mptt.models import MPTTModel from dcim.choices import CableLengthUnitChoices +from extras.plugins import PluginConfig from extras.utils import is_taggable from utilities.constants import HTTP_REQUEST_META_SAFE_COPY +def resolve_namespace(instance): + """ + Get the appropriate namepsace for the app based on whether it is a Plugin or base application + """ + if isinstance(instance._meta.app_config, PluginConfig): + return f'plugins:{instance._meta.app_label}' + return f'{instance._meta.app_label}' + + def csv_format(data): """ Encapsulate any data which contains a comma within double quotes.