2
0

jinja2.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. from django.apps import apps
  2. from jinja2 import BaseLoader, TemplateNotFound
  3. from jinja2.meta import find_referenced_templates
  4. from jinja2.sandbox import SandboxedEnvironment
  5. from netbox.config import get_config
  6. __all__ = (
  7. 'DataFileLoader',
  8. )
  9. class DataFileLoader(BaseLoader):
  10. """
  11. Custom Jinja2 loader to facilitate populating template content from DataFiles.
  12. """
  13. def __init__(self, data_source):
  14. self.data_source = data_source
  15. self._template_cache = {}
  16. def get_source(self, environment, template):
  17. DataFile = apps.get_model('core', 'DataFile')
  18. # Retrieve template content from cache
  19. try:
  20. template_source = self._template_cache[template]
  21. except KeyError:
  22. raise TemplateNotFound(template)
  23. # Find and pre-fetch referenced templates
  24. if referenced_templates := find_referenced_templates(environment.parse(template_source)):
  25. self.cache_templates({
  26. df.path: df.data_as_string for df in
  27. DataFile.objects.filter(source=self.data_source, path__in=referenced_templates)
  28. })
  29. return template_source, template, lambda: True
  30. def cache_templates(self, templates):
  31. self._template_cache.update(templates)
  32. #
  33. # Utility functions
  34. #
  35. def render_jinja2(template_code, context):
  36. """
  37. Render a Jinja2 template with the provided context. Return the rendered content.
  38. """
  39. environment = SandboxedEnvironment()
  40. environment.filters.update(get_config().JINJA2_FILTERS)
  41. return environment.from_string(source=template_code).render(**context)