diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index 23ca44cc83..f98a1b1cdc 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -67,7 +67,7 @@ class InvenTreePluginMixin: """ - def get_plugin_panels(self): + def get_plugin_panels(self, ctx): """ Return a list of extra 'plugin panels' associated with this view """ @@ -75,7 +75,7 @@ class InvenTreePluginMixin: panels = [] for plug in registry.with_mixin('panel'): - panels += plug.render_panels(self, self.request) + panels += plug.render_panels(self, self.request, ctx) return panels @@ -84,7 +84,7 @@ class InvenTreePluginMixin: ctx = super().get_context_data(**kwargs) if settings.PLUGINS_ENABLED: - ctx['plugin_panels'] = self.get_plugin_panels() + ctx['plugin_panels'] = self.get_plugin_panels(ctx) return ctx diff --git a/InvenTree/plugin/builtin/integration/mixins.py b/InvenTree/plugin/builtin/integration/mixins.py index b5040de78f..d50a9ce729 100644 --- a/InvenTree/plugin/builtin/integration/mixins.py +++ b/InvenTree/plugin/builtin/integration/mixins.py @@ -11,9 +11,10 @@ from django.db.utils import OperationalError, ProgrammingError import InvenTree.helpers -from plugin.models import PluginConfig, PluginSetting -from plugin.urls import PLUGIN_BASE from plugin.helpers import MixinImplementationError, MixinNotImplementedError +from plugin.models import PluginConfig, PluginSetting +from plugin.template import render_template +from plugin.urls import PLUGIN_BASE logger = logging.getLogger('inventree') @@ -599,19 +600,50 @@ class PanelMixin: super().__init__() self.add_mixin('panel', True, __class__) - def render_panels(self, view, request): + def get_custom_panels(self, view, request): + """ This method *must* be implemented by the plugin class """ + raise NotImplementedError(f"{__class__} is missing the 'get_custom_panels' method") + + def get_panel_context(self, view, request, context): + """ + Build the context data to be used for template rendering. + Custom class can override this to provide any custom context data. + + (See the example in "custom_panel_sample.py") + """ + + # Provide some standard context items to the template for rendering + context['plugin'] = self + context['request'] = request + context['user'] = getattr(request, 'user', None) + context['view'] = view + + try: + context['object'] = view.get_object() + except AttributeError: + pass + + return context + + def render_panels(self, view, request, context): panels = [] + # Construct an updated context object for template rendering + ctx = self.get_panel_context(view, request, context) + for panel in self.get_custom_panels(view, request): - if 'content_template' in panel: - # TODO: Render the actual HTML content from a template file - ... + content_template = panel.get('content_template', None) + javascript_template = panel.get('javascript_template', None) - if 'javascript_template' in panel: - # TODO: Render the actual javascript content from a template file - ... + if content_template: + # Render content template to HTML + panel['content'] = render_template(self, content_template, ctx) + + if javascript_template: + # Render javascript template to HTML + panel['javascript'] = render_template(self, javascript_template, ctx) # Check for required keys required_keys = ['title', 'content'] @@ -630,7 +662,3 @@ class PanelMixin: panels.append(panel) return panels - - def get_custom_panels(self, view, request): - """ This method *must* be implemented by the plugin class """ - raise NotImplementedError(f"{__class__} is missing the 'get_custom_panels' method") diff --git a/InvenTree/plugin/samples/integration/custom_panel_sample.py b/InvenTree/plugin/samples/integration/custom_panel_sample.py index 0eada9c8ab..e0b84fe01a 100644 --- a/InvenTree/plugin/samples/integration/custom_panel_sample.py +++ b/InvenTree/plugin/samples/integration/custom_panel_sample.py @@ -29,18 +29,15 @@ class CustomPanelSample(PanelMixin, SettingsMixin, IntegrationPluginBase): } } - def render_location_info(self, loc): - """ - Demonstrate that we can render information particular to a page - """ - return f""" -
Location Information
- This location has no sublocations! - - """ + def get_panel_context(self, view, request, context): + + ctx = super().get_panel_context(view, request, context) + + # If we are looking at a StockLocationDetail view, add location context object + if isinstance(view, StockLocationDetail): + ctx['location'] = view.get_object() + + return ctx def get_custom_panels(self, view, request): @@ -89,7 +86,7 @@ class CustomPanelSample(PanelMixin, SettingsMixin, IntegrationPluginBase): panels.append({ 'title': 'Childless Location', 'icon': 'fa-user', - 'content': self.render_location_info(loc), + 'content_template': 'panel_demo/childless.html', # Note that the panel content is rendered using a template file! }) except: pass diff --git a/InvenTree/plugin/samples/integration/templates/panel_demo/childless.html b/InvenTree/plugin/samples/integration/templates/panel_demo/childless.html new file mode 100644 index 0000000000..061dcc514d --- /dev/null +++ b/InvenTree/plugin/samples/integration/templates/panel_demo/childless.html @@ -0,0 +1,11 @@ +

Template Rendering

+ +
+ This panel has been rendered using a template file! +
+ +This location has no sublocations! + diff --git a/InvenTree/plugin/template.py b/InvenTree/plugin/template.py index 7e1da81609..0f580a8023 100644 --- a/InvenTree/plugin/template.py +++ b/InvenTree/plugin/template.py @@ -45,10 +45,6 @@ def render_template(plugin, template_file, context=None): Locate and render a template file, available in the global template context. """ - print("render_template", "->", template_file) - print("Context:") - print(context) - try: tmp = template.loader.get_template(template_file) except template.TemplateDoesNotExist: