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.

jinja2.py 4.0KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. from pathlib import Path
  2. import jinja2
  3. from django.conf import settings
  4. from django.template import TemplateDoesNotExist, TemplateSyntaxError
  5. from django.utils.functional import cached_property
  6. from django.utils.module_loading import import_string
  7. from .base import BaseEngine
  8. class Jinja2(BaseEngine):
  9. app_dirname = "jinja2"
  10. def __init__(self, params):
  11. params = params.copy()
  12. options = params.pop("OPTIONS").copy()
  13. super().__init__(params)
  14. self.context_processors = options.pop("context_processors", [])
  15. environment = options.pop("environment", "jinja2.Environment")
  16. environment_cls = import_string(environment)
  17. if "loader" not in options:
  18. options["loader"] = jinja2.FileSystemLoader(self.template_dirs)
  19. options.setdefault("autoescape", True)
  20. options.setdefault("auto_reload", settings.DEBUG)
  21. options.setdefault(
  22. "undefined", jinja2.DebugUndefined if settings.DEBUG else jinja2.Undefined
  23. )
  24. self.env = environment_cls(**options)
  25. def from_string(self, template_code):
  26. return Template(self.env.from_string(template_code), self)
  27. def get_template(self, template_name):
  28. try:
  29. return Template(self.env.get_template(template_name), self)
  30. except jinja2.TemplateNotFound as exc:
  31. raise TemplateDoesNotExist(exc.name, backend=self) from exc
  32. except jinja2.TemplateSyntaxError as exc:
  33. new = TemplateSyntaxError(exc.args)
  34. new.template_debug = get_exception_info(exc)
  35. raise new from exc
  36. @cached_property
  37. def template_context_processors(self):
  38. return [import_string(path) for path in self.context_processors]
  39. class Template:
  40. def __init__(self, template, backend):
  41. self.template = template
  42. self.backend = backend
  43. self.origin = Origin(
  44. name=template.filename,
  45. template_name=template.name,
  46. )
  47. def render(self, context=None, request=None):
  48. from .utils import csrf_input_lazy, csrf_token_lazy
  49. if context is None:
  50. context = {}
  51. if request is not None:
  52. context["request"] = request
  53. context["csrf_input"] = csrf_input_lazy(request)
  54. context["csrf_token"] = csrf_token_lazy(request)
  55. for context_processor in self.backend.template_context_processors:
  56. context.update(context_processor(request))
  57. try:
  58. return self.template.render(context)
  59. except jinja2.TemplateSyntaxError as exc:
  60. new = TemplateSyntaxError(exc.args)
  61. new.template_debug = get_exception_info(exc)
  62. raise new from exc
  63. class Origin:
  64. """
  65. A container to hold debug information as described in the template API
  66. documentation.
  67. """
  68. def __init__(self, name, template_name):
  69. self.name = name
  70. self.template_name = template_name
  71. def get_exception_info(exception):
  72. """
  73. Format exception information for display on the debug page using the
  74. structure described in the template API documentation.
  75. """
  76. context_lines = 10
  77. lineno = exception.lineno
  78. source = exception.source
  79. if source is None:
  80. exception_file = Path(exception.filename)
  81. if exception_file.exists():
  82. source = exception_file.read_text()
  83. if source is not None:
  84. lines = list(enumerate(source.strip().split("\n"), start=1))
  85. during = lines[lineno - 1][1]
  86. total = len(lines)
  87. top = max(0, lineno - context_lines - 1)
  88. bottom = min(total, lineno + context_lines)
  89. else:
  90. during = ""
  91. lines = []
  92. total = top = bottom = 0
  93. return {
  94. "name": exception.filename,
  95. "message": exception.message,
  96. "source_lines": lines[top:bottom],
  97. "line": lineno,
  98. "before": "",
  99. "during": during,
  100. "after": "",
  101. "total": total,
  102. "top": top,
  103. "bottom": bottom,
  104. }