diff --git a/docs/plugins/development.md b/docs/plugins/development.md index f56852cbd..b48a329fb 100644 --- a/docs/plugins/development.md +++ b/docs/plugins/development.md @@ -106,7 +106,7 @@ class AnimalSoundsConfig(PluginConfig): | `max_version` | Maximum version of NetBox with which the plugin is compatible | | `middleware` | A list of middleware classes to append after NetBox's build-in middleware | | `caching_config` | Plugin-specific cache configuration -| `template_content` | The dotted path to the list of template content classes (default: `template_content.template_contnet`) | +| `template_extensions` | The dotted path to the list of template extension classes (default: `template_content.template_extensions`) | | `menu_items` | The dotted path to the list of menu items provided by the plugin (default: `navigation.menu_items`) | ### Install the Plugin for Development @@ -317,9 +317,9 @@ A `PluginMenuButton` has the following attributes: * `color` - One of the choices provided by `ButtonColorChoices` (optional) * `permission` - The name of the permission required to display this button (optional) -## Template Content +## Extending Core Templates -Plugins can inject custom content into certain areas of the detail views of applicable models. This is accomplished by subclassing `PluginTemplateContent`, designating a particular NetBox model, and defining the desired methods to render custom content. Four methods are available: +Plugins can inject custom content into certain areas of the detail views of applicable models. This is accomplished by subclassing `PluginTemplateExtension`, designating a particular NetBox model, and defining the desired methods to render custom content. Four methods are available: * `left_page()` - Inject content on the left side of the page * `right_page()` - Inject content on the right side of the page @@ -333,25 +333,25 @@ Each of these methods must return HTML content suitable for inclusion in the obj 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. -Declared subclasses should be gathered into a list or tuple for integration with NetBox. By default, NetBox looks for an iterable named `template_content` within a `template_content.py` file. (This can be overridden by setting `template_content` to a custom value on the plugin's PluginConfig.) An example is below. +Declared subclasses should be gathered into a list or tuple for integration with NetBox. By default, NetBox looks for an iterable named `template_extensions` within a `template_content.py` file. (This can be overridden by setting `template_extensions` to a custom value on the plugin's PluginConfig.) An example is below. ```python -from extras.plugins import PluginTemplateContent +from extras.plugins import PluginTemplateExtension -class AddSiteAnimal(PluginTemplateContent): +class AddSiteAnimal(PluginTemplateExtension): model = 'dcim.site' def full_width_page(self): return self.render('netbox_animal_sounds/site.html') -class AddRackAnimal(PluginTemplateContent): +class AddRackAnimal(PluginTemplateExtension): model = 'dcim.rack' def left_page(self): extra_data = {'foo': 123} return self.render('netbox_animal_sounds/rack.html', extra_data) -template_content_classes = [AddSiteAnimal, AddRackAnimal] +template_extensions = [AddSiteAnimal, AddRackAnimal] ``` ## Caching Configuration diff --git a/netbox/extras/plugins/__init__.py b/netbox/extras/plugins/__init__.py index b133f83a0..b16f70b1a 100644 --- a/netbox/extras/plugins/__init__.py +++ b/netbox/extras/plugins/__init__.py @@ -10,7 +10,7 @@ from utilities.choices import ButtonColorChoices # Initialize plugin registry stores -registry['plugin_template_content_classes'] = collections.defaultdict(list) +registry['plugin_template_extensions'] = collections.defaultdict(list) registry['plugin_nav_menu_links'] = {} @@ -49,15 +49,15 @@ class PluginConfig(AppConfig): # Default integration paths. Plugin authors can override these to customize the paths to # integrated components. - template_content_classes = 'template_content.template_content_classes' + template_extensions = 'template_content.template_extensions' menu_items = 'navigation.menu_items' def ready(self): # Register template content try: - class_list = import_string(f"{self.__module__}.{self.template_content_classes}") - register_template_content_classes(class_list) + template_extensions = import_string(f"{self.__module__}.{self.template_extensions}") + register_template_extensions(template_extensions) except ImportError: pass @@ -73,7 +73,7 @@ class PluginConfig(AppConfig): # Template content injection # -class PluginTemplateContent: +class PluginTemplateExtension: """ This class is used to register plugin content to be injected into core NetBox templates. It contains methods that are overridden by plugin authors to return template content. @@ -132,20 +132,20 @@ class PluginTemplateContent: raise NotImplementedError -def register_template_content_classes(class_list): +def register_template_extensions(class_list): """ - Register a list of PluginTemplateContent classes + Register a list of PluginTemplateExtension classes """ # Validation - for template_content_class in class_list: - if not inspect.isclass(template_content_class): - raise TypeError('Plugin content class {} was passes as an instance!'.format(template_content_class)) - if not issubclass(template_content_class, PluginTemplateContent): - raise TypeError('{} is not a subclass of extras.plugins.PluginTemplateContent!'.format(template_content_class)) - if template_content_class.model is None: - raise TypeError('Plugin content class {} does not define a valid model!'.format(template_content_class)) + for template_extension in class_list: + if not inspect.isclass(template_extension): + raise TypeError(f"PluginTemplateExtension class {template_extension} was passes as an instance!") + if not issubclass(template_extension, PluginTemplateExtension): + raise TypeError(f"{template_extension} is not a subclass of extras.plugins.PluginTemplateExtension!") + if template_extension.model is None: + raise TypeError(f"PluginTemplateExtension class {template_extension} does not define a valid model!") - registry['plugin_template_content_classes'][template_content_class.model].append(template_content_class) + registry['plugin_template_extensions'][template_extension.model].append(template_extension) # diff --git a/netbox/extras/templatetags/plugins.py b/netbox/extras/templatetags/plugins.py index d2b10669a..b867819ba 100644 --- a/netbox/extras/templatetags/plugins.py +++ b/netbox/extras/templatetags/plugins.py @@ -8,13 +8,13 @@ register = template_.Library() def _get_registered_content(obj, method, context): """ - Given an object and a PluginTemplateContent method name and the template context, return all the + Given an object and a PluginTemplateExtension method name and the template context, return all the registered content for the object's model. """ html = '' model_name = obj._meta.label_lower - plugin_template_classes = registry['plugin_template_content_classes'].get(model_name, []) + plugin_template_classes = registry['plugin_template_extensions'].get(model_name, []) for plugin_template_class in plugin_template_classes: plugin_template_renderer = plugin_template_class(obj, context) try: