Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

django.py 4.3KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. from importlib import import_module
  2. from pkgutil import walk_packages
  3. from django.apps import apps
  4. from django.conf import settings
  5. from django.template import TemplateDoesNotExist
  6. from django.template.context import make_context
  7. from django.template.engine import Engine
  8. from django.template.library import InvalidTemplateLibrary
  9. from .base import BaseEngine
  10. class DjangoTemplates(BaseEngine):
  11. app_dirname = "templates"
  12. def __init__(self, params):
  13. params = params.copy()
  14. options = params.pop("OPTIONS").copy()
  15. options.setdefault("autoescape", True)
  16. options.setdefault("debug", settings.DEBUG)
  17. options.setdefault("file_charset", "utf-8")
  18. libraries = options.get("libraries", {})
  19. options["libraries"] = self.get_templatetag_libraries(libraries)
  20. super().__init__(params)
  21. self.engine = Engine(self.dirs, self.app_dirs, **options)
  22. def from_string(self, template_code):
  23. return Template(self.engine.from_string(template_code), self)
  24. def get_template(self, template_name):
  25. try:
  26. return Template(self.engine.get_template(template_name), self)
  27. except TemplateDoesNotExist as exc:
  28. reraise(exc, self)
  29. def get_templatetag_libraries(self, custom_libraries):
  30. """
  31. Return a collation of template tag libraries from installed
  32. applications and the supplied custom_libraries argument.
  33. """
  34. libraries = get_installed_libraries()
  35. libraries.update(custom_libraries)
  36. return libraries
  37. class Template:
  38. def __init__(self, template, backend):
  39. self.template = template
  40. self.backend = backend
  41. @property
  42. def origin(self):
  43. return self.template.origin
  44. def render(self, context=None, request=None):
  45. context = make_context(
  46. context, request, autoescape=self.backend.engine.autoescape
  47. )
  48. try:
  49. return self.template.render(context)
  50. except TemplateDoesNotExist as exc:
  51. reraise(exc, self.backend)
  52. def copy_exception(exc, backend=None):
  53. """
  54. Create a new TemplateDoesNotExist. Preserve its declared attributes and
  55. template debug data but discard __traceback__, __context__, and __cause__
  56. to make this object suitable for keeping around (in a cache, for example).
  57. """
  58. backend = backend or exc.backend
  59. new = exc.__class__(*exc.args, tried=exc.tried, backend=backend, chain=exc.chain)
  60. if hasattr(exc, "template_debug"):
  61. new.template_debug = exc.template_debug
  62. return new
  63. def reraise(exc, backend):
  64. """
  65. Reraise TemplateDoesNotExist while maintaining template debug information.
  66. """
  67. new = copy_exception(exc, backend)
  68. raise new from exc
  69. def get_template_tag_modules():
  70. """
  71. Yield (module_name, module_path) pairs for all installed template tag
  72. libraries.
  73. """
  74. candidates = ["django.templatetags"]
  75. candidates.extend(
  76. f"{app_config.name}.templatetags" for app_config in apps.get_app_configs()
  77. )
  78. for candidate in candidates:
  79. try:
  80. pkg = import_module(candidate)
  81. except ImportError:
  82. # No templatetags package defined. This is safe to ignore.
  83. continue
  84. if hasattr(pkg, "__path__"):
  85. for name in get_package_libraries(pkg):
  86. yield name[len(candidate) + 1 :], name
  87. def get_installed_libraries():
  88. """
  89. Return the built-in template tag libraries and those from installed
  90. applications. Libraries are stored in a dictionary where keys are the
  91. individual module names, not the full module paths. Example:
  92. django.templatetags.i18n is stored as i18n.
  93. """
  94. return {
  95. module_name: full_name for module_name, full_name in get_template_tag_modules()
  96. }
  97. def get_package_libraries(pkg):
  98. """
  99. Recursively yield template tag libraries defined in submodules of a
  100. package.
  101. """
  102. for entry in walk_packages(pkg.__path__, pkg.__name__ + "."):
  103. try:
  104. module = import_module(entry[1])
  105. except ImportError as e:
  106. raise InvalidTemplateLibrary(
  107. "Invalid template library specified. ImportError raised when "
  108. "trying to load '%s': %s" % (entry[1], e)
  109. ) from e
  110. if hasattr(module, "register"):
  111. yield entry[1]