Skip to content

Commit

Permalink
Closes #16726: Extend PluginTemplateExtension to allow registering mu…
Browse files Browse the repository at this point in the history
…ltiple models
  • Loading branch information
jeremystretch committed Jul 1, 2024
1 parent c22463f commit 1820247
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 8 deletions.
8 changes: 5 additions & 3 deletions docs/plugins/development/views.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
|---------------------|-------------|-----------------------------------------------------|
Expand All @@ -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)
Expand All @@ -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={
Expand Down
14 changes: 12 additions & 2 deletions netbox/netbox/plugins/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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):
Expand Down
1 change: 1 addition & 0 deletions netbox/netbox/plugins/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class PluginTemplateExtension:
* settings - Global NetBox settings
* config - Plugin-specific configuration parameters
"""
models = None
model = None

def __init__(self, context):
Expand Down
2 changes: 1 addition & 1 deletion netbox/netbox/tests/dummy_plugin/template_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def navbar(self):


class SiteContent(PluginTemplateExtension):
model = 'dcim.site'
models = ['dcim.site']

def left_page(self):
return "SITE CONTENT - LEFT PAGE"
Expand Down
6 changes: 4 additions & 2 deletions netbox/utilities/templatetags/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 1820247

Please sign in to comment.