|
8 | 8 | from docutils.utils import SystemMessage |
9 | 9 | import debug # pyflakes:ignore |
10 | 10 |
|
| 11 | +from django.template import Origin, TemplateDoesNotExist, Template as DjangoTemplate |
11 | 12 | from django.template.loaders.base import Loader as BaseLoader |
12 | | -from django.template.base import Template as DjangoTemplate, TemplateEncodingError # type: ignore |
13 | | -from django.template.exceptions import TemplateDoesNotExist |
14 | | -from django.utils.encoding import smart_text |
15 | 13 |
|
16 | 14 | from ietf.dbtemplate.models import DBTemplate |
17 | 15 |
|
|
20 | 18 | RST_TEMPLATE = os.path.join(BASE_DIR, 'resources/rst.txt') |
21 | 19 |
|
22 | 20 |
|
23 | | -class Template(object): |
| 21 | +class Template(DjangoTemplate): |
24 | 22 |
|
25 | | - def __init__(self, template_string, origin=None, name='<Unknown Template>'): |
26 | | - try: |
27 | | - template_string = smart_text(template_string) |
28 | | - except UnicodeDecodeError: |
29 | | - raise TemplateEncodingError("Templates can only be constructed from unicode or UTF-8 strings.") |
| 23 | + def __init__(self, template_string, origin=None, name='<Unknown Template>', engine=None): |
| 24 | + super(Template, self).__init__(template_string, origin, name, engine) |
30 | 25 | self.template_string = string.Template(template_string) |
31 | | - self.name = name |
32 | 26 |
|
33 | 27 | def render(self, context): |
34 | 28 | raise NotImplementedError |
@@ -70,27 +64,43 @@ def __init__(self, engine): |
70 | 64 | super(Loader, self).__init__(engine) |
71 | 65 | self.is_usable = True |
72 | 66 |
|
73 | | - def load_template(self, template_name, template_dirs=None): |
74 | | - try: |
75 | | - template = DBTemplate.objects.get(path=template_name) |
76 | | - if template.type.slug == 'rst': |
77 | | - return (RSTTemplate(template.content), template) |
78 | | - elif template.type.slug == 'django': |
79 | | - return (DjangoTemplate(template.content), template) |
80 | | - return (PlainTemplate(template.content), template) |
81 | | - except DBTemplate.DoesNotExist: |
82 | | - raise TemplateDoesNotExist(template_name) |
83 | | - |
84 | | - |
85 | | -_loader = Loader(engine='django') |
86 | | - |
87 | | - |
88 | | -def load_template_source(template_name, template_dirs=None): |
89 | | - # For backwards compatibility |
90 | | - import warnings |
91 | | - warnings.warn( |
92 | | - "'ietf.dbtemplate.template.load_template_source' is deprecated; use 'ietf.dbtemplate.template.Loader' instead.", |
93 | | - PendingDeprecationWarning |
94 | | - ) |
95 | | - return _loader.load_template_source(template_name, template_dirs) |
96 | | -load_template_source.is_usable = True # type: ignore # https://github.com/python/mypy/issues/2087 |
| 67 | + def get_template(self, template_name, skip=None): |
| 68 | + """ |
| 69 | + Call self.get_template_sources() and return a Template object for |
| 70 | + the first template matching template_name. If skip is provided, ignore |
| 71 | + template origins in skip. This is used to avoid recursion during |
| 72 | + template extending. |
| 73 | + """ |
| 74 | + tried = [] |
| 75 | + |
| 76 | + for origin in self.get_template_sources(template_name): |
| 77 | + if skip is not None and origin in skip: |
| 78 | + tried.append((origin, 'Skipped')) |
| 79 | + continue |
| 80 | + |
| 81 | + try: |
| 82 | + template = DBTemplate.objects.get(path=origin) |
| 83 | + contents = template.content |
| 84 | + except DBTemplate.DoesNotExist: |
| 85 | + tried.append((origin, 'Source does not exist')) |
| 86 | + continue |
| 87 | + else: |
| 88 | + if template.type_id == 'rst': |
| 89 | + return RSTTemplate(contents, origin, origin.template_name, self.engine) |
| 90 | + elif template.type_id == 'plain': |
| 91 | + return PlainTemplate(contents, origin, origin.template_name, self.engine) |
| 92 | + elif template.type_id == 'django': |
| 93 | + return DjangoTemplate(contents, origin, origin.template_name, self.engine) |
| 94 | + else: |
| 95 | + return Template(contents, origin, origin.template_name, self.engine) |
| 96 | + |
| 97 | + raise TemplateDoesNotExist(template_name, tried=tried) |
| 98 | + |
| 99 | + def get_template_sources(self, template_name): |
| 100 | + for template in DBTemplate.objects.filter(path__endswith=template_name): |
| 101 | + yield Origin( |
| 102 | + name=template.path, |
| 103 | + template_name=template_name, |
| 104 | + loader=self, |
| 105 | + ) |
| 106 | + |
0 commit comments