forked from adamlaska/datatracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtemplate.py
More file actions
106 lines (83 loc) · 3.89 KB
/
template.py
File metadata and controls
106 lines (83 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# Copyright The IETF Trust 2012-2020, All Rights Reserved
# -*- coding: utf-8 -*-
import os
import string
from docutils.core import publish_string
from docutils.utils import SystemMessage
import debug # pyflakes:ignore
from django.template import Origin, TemplateDoesNotExist, Template as DjangoTemplate
from django.template.loaders.base import Loader as BaseLoader
from django.utils.safestring import mark_safe
from ietf.dbtemplate.models import DBTemplate
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
RST_TEMPLATE = os.path.join(BASE_DIR, 'resources/rst.txt')
class Template(DjangoTemplate):
def __init__(self, template_string, origin=None, name='<Unknown Template>', engine=None):
super(Template, self).__init__(template_string, origin, name, engine)
self.template_string = string.Template(template_string)
def render(self, context):
raise NotImplementedError
class PlainTemplate(Template):
def render(self, context):
context_dict = {}
for d in context.dicts:
context_dict.update(d)
return self.template_string.safe_substitute(context_dict)
class RSTTemplate(PlainTemplate):
def render(self, context):
interpolated_string = super(RSTTemplate, self).render(context)
try:
return publish_string(source=interpolated_string,
writer_name='html',
settings_overrides={
'input_encoding': 'unicode',
'output_encoding': 'unicode',
'embed_stylesheet': False,
'xml_declaration': False,
'template': RST_TEMPLATE,
'halt_level': 2,
})
except SystemMessage as e:
args = list(e.args)
args[0] = mark_safe('<div class="danger preformatted">%s</div>' % args[0].replace('<string>:', 'line '))
e.args = tuple(args)
raise e
class Loader(BaseLoader):
def __init__(self, engine):
super(Loader, self).__init__(engine)
self.is_usable = True
def get_template(self, template_name, skip=None):
"""
Call self.get_template_sources() and return a Template object for
the first template matching template_name. If skip is provided, ignore
template origins in skip. This is used to avoid recursion during
template extending.
"""
tried = []
for origin in self.get_template_sources(template_name):
if skip is not None and origin in skip:
tried.append((origin, 'Skipped'))
continue
try:
template = DBTemplate.objects.get(path=origin)
contents = template.content
except DBTemplate.DoesNotExist:
tried.append((origin, 'Source does not exist'))
continue
else:
if template.type_id == 'rst':
return RSTTemplate(contents, origin, origin.template_name, self.engine)
elif template.type_id == 'plain':
return PlainTemplate(contents, origin, origin.template_name, self.engine)
elif template.type_id == 'django':
return DjangoTemplate(contents, origin, origin.template_name, self.engine)
else:
return Template(contents, origin, origin.template_name, self.engine)
raise TemplateDoesNotExist(template_name, tried=tried)
def get_template_sources(self, template_name):
for template in DBTemplate.objects.filter(path__endswith=template_name):
yield Origin(
name=template.path,
template_name=template_name,
loader=self,
)