Bläddra i källkod

Closes #16726: Extend PluginTemplateExtension to allow registering multiple models

Jeremy Stretch 1 år sedan
förälder
incheckning
82d8de32df

+ 5 - 3
docs/plugins/development/views.md

@@ -191,7 +191,7 @@ class MyView(generic.ObjectView):
 
 ### Extra Template Content
 
-Plugins can inject custom content into certain areas of core NetBox views. This is accomplished by subclassing `PluginTemplateExtension`, designating a particular NetBox model, and defining the desired method(s) to render custom content. Five methods are available:
+Plugins can inject custom content into certain areas of core NetBox views. This is accomplished by subclassing `PluginTemplateExtension`, optionally designating one or more particular NetBox models, and defining the desired method(s) to render custom content. Five methods are available:
 
 | Method              | View        | Description                                         |
 |---------------------|-------------|-----------------------------------------------------|
@@ -206,7 +206,9 @@ Plugins can inject custom content into certain areas of core NetBox views. This
 
 Additionally, a `render()` method is available for convenience. This method accepts the name of a template to render, and any additional context data you want to pass. Its use is optional, however.
 
-When a PluginTemplateExtension is instantiated, context data is assigned to `self.context`. Available data include:
+To control where the custom content is injected, plugin authors can specify an iterable of models by overriding the `models` attribute on the subclass. Extensions which do not specify a set of models will be invoked on every view, where supported.
+
+When a PluginTemplateExtension is instantiated, context data is assigned to `self.context`. Available data includes:
 
 * `object` - The object being viewed (object views only)
 * `model` - The model of the list view (list views only)
@@ -223,7 +225,7 @@ from netbox.plugins import PluginTemplateExtension
 from .models import Animal
 
 class SiteAnimalCount(PluginTemplateExtension):
-    model = 'dcim.site'
+    models = ['dcim.site']
 
     def right_page(self):
         return self.render('netbox_animal_sounds/inc/animal_count.html', extra_context={

+ 12 - 2
netbox/netbox/plugins/registration.py

@@ -18,8 +18,8 @@ def register_template_extensions(class_list):
     """
     Register a list of PluginTemplateExtension classes
     """
-    # Validation
     for template_extension in class_list:
+        # Validation
         if not inspect.isclass(template_extension):
             raise TypeError(
                 _("PluginTemplateExtension class {template_extension} was passed as an instance!").format(
@@ -33,7 +33,17 @@ def register_template_extensions(class_list):
                 )
             )
 
-        registry['plugins']['template_extensions'][template_extension.model].append(template_extension)
+        if template_extension.models:
+            # Registration for multiple models
+            models = template_extension.models
+        elif template_extension.model:
+            # Registration for a single model
+            models = [template_extension.model]
+        else:
+            # Global registration (no specific models)
+            models = [None]
+        for model in models:
+            registry['plugins']['template_extensions'][model].append(template_extension)
 
 
 def register_menu(menu):

+ 1 - 0
netbox/netbox/plugins/templates.py

@@ -20,6 +20,7 @@ class PluginTemplateExtension:
     * settings - Global NetBox settings
     * config - Plugin-specific configuration parameters
     """
+    models = None
     model = None
 
     def __init__(self, context):

+ 1 - 1
netbox/netbox/tests/dummy_plugin/template_content.py

@@ -8,7 +8,7 @@ class GlobalContent(PluginTemplateExtension):
 
 
 class SiteContent(PluginTemplateExtension):
-    model = 'dcim.site'
+    models = ['dcim.site']
 
     def left_page(self):
         return "SITE CONTENT - LEFT PAGE"

+ 4 - 2
netbox/utilities/templatetags/plugins.py

@@ -22,8 +22,10 @@ def _get_registered_content(obj, method, template_context):
         'perms': template_context['perms'],
     }
 
-    model_name = obj._meta.label_lower if obj is not None else None
-    template_extensions = registry['plugins']['template_extensions'].get(model_name, [])
+    template_extensions = registry['plugins']['template_extensions'].get(None, [])
+    if obj is not None:
+        model_name = obj._meta.label_lower
+        template_extensions.extend(registry['plugins']['template_extensions'].get(model_name, []))
     for template_extension in template_extensions:
 
         # If the class has not overridden the specified method, we can skip it (because we know it