##// END OF EJS Templates
improve template errors when something is wrong.
Vadim Gelfer -
r1905:0c760737 default
parent child Browse files
Show More
@@ -32,28 +32,33 b' def parsestring(s, quoted=True):'
32
32
33 class templater(object):
33 class templater(object):
34 def __init__(self, mapfile, filters={}, defaults={}):
34 def __init__(self, mapfile, filters={}, defaults={}):
35 self.mapfile = mapfile or 'template'
35 self.cache = {}
36 self.cache = {}
36 self.map = {}
37 self.map = {}
37 self.base = os.path.dirname(mapfile)
38 self.base = (mapfile and os.path.dirname(mapfile)) or ''
38 self.filters = filters
39 self.filters = filters
39 self.defaults = defaults
40 self.defaults = defaults
40
41
42 if not mapfile:
43 return
41 i = 0
44 i = 0
42 for l in file(mapfile):
45 for l in file(mapfile):
46 l = l.rstrip('\r\n')
43 i += 1
47 i += 1
44 m = re.match(r'(\S+)\s*=\s*(["\'].*["\'])$', l)
48 if l.startswith('#') or not l.strip(): continue
49 m = re.match(r'([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+)$', l)
45 if m:
50 if m:
46 try:
51 key, val = m.groups()
47 s = m.group(2)
52 if val[0] in "'\"":
48 self.cache[m.group(1)] = parsestring(s)
53 try:
49 except SyntaxError, inst:
54 self.cache[key] = parsestring(val)
50 raise SyntaxError('%s:%s: %s' % (mapfile, i, inst.args[0]))
55 except SyntaxError, inst:
56 raise SyntaxError('%s:%s: %s' %
57 (mapfile, i, inst.args[0]))
58 else:
59 self.map[key] = os.path.join(self.base, val)
51 else:
60 else:
52 m = re.match(r'(\S+)\s*=\s*(\S+)', l)
61 raise SyntaxError(_("%s:%s: parse error") % (mapfile, i))
53 if m:
54 self.map[m.group(1)] = os.path.join(self.base, m.group(2))
55 else:
56 raise LookupError(_("unknown map entry '%s'") % l)
57
62
58 def __contains__(self, key):
63 def __contains__(self, key):
59 return key in self.cache
64 return key in self.cache
@@ -64,7 +69,11 b' class templater(object):'
64 try:
69 try:
65 tmpl = self.cache[t]
70 tmpl = self.cache[t]
66 except KeyError:
71 except KeyError:
67 tmpl = self.cache[t] = file(self.map[t]).read()
72 try:
73 tmpl = self.cache[t] = file(self.map[t]).read()
74 except IOError, inst:
75 raise IOError(inst.args[0], _('template file %s: %s') %
76 (self.map[t], inst.args[1]))
68 return self.template(tmpl, self.filters, **m)
77 return self.template(tmpl, self.filters, **m)
69
78
70 template_re = re.compile(r"[#{]([a-zA-Z_][a-zA-Z0-9_]*)"
79 template_re = re.compile(r"[#{]([a-zA-Z_][a-zA-Z0-9_]*)"
@@ -76,10 +85,15 b' class templater(object):'
76 while tmpl:
85 while tmpl:
77 m = self.template_re.search(tmpl)
86 m = self.template_re.search(tmpl)
78 if m:
87 if m:
79 start = m.start(0)
88 start, end = m.span(0)
89 s, e = tmpl[start], tmpl[end - 1]
90 key = m.group(1)
91 if ((s == '#' and e != '#') or (s == '{' and e != '}')):
92 raise SyntaxError(_("'%s'/'%s' mismatch expanding '%s'") %
93 (s, e, key))
80 if start:
94 if start:
81 yield tmpl[:start]
95 yield tmpl[:start]
82 v = map.get(m.group(1), "")
96 v = map.get(key, "")
83 v = callable(v) and v(**map) or v
97 v = callable(v) and v(**map) or v
84
98
85 format = m.group(2)
99 format = m.group(2)
@@ -98,7 +112,7 b' class templater(object):'
98 v = filters[f](v)
112 v = filters[f](v)
99
113
100 yield v
114 yield v
101 tmpl = tmpl[m.end(0):]
115 tmpl = tmpl[end:]
102 else:
116 else:
103 yield tmpl
117 yield tmpl
104 break
118 break
@@ -153,9 +167,9 b' common_filters = {'
153 "addbreaks": nl2br,
167 "addbreaks": nl2br,
154 "age": age,
168 "age": age,
155 "date": lambda x: util.datestr(x),
169 "date": lambda x: util.datestr(x),
170 "domain": domain,
156 "escape": lambda x: cgi.escape(x, True),
171 "escape": lambda x: cgi.escape(x, True),
157 "firstline": (lambda x: x.splitlines(1)[0]),
172 "firstline": (lambda x: x.splitlines(1)[0]),
158 "domain": domain,
159 "obfuscate": obfuscate,
173 "obfuscate": obfuscate,
160 "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--"),
174 "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--"),
161 "person": person,
175 "person": person,
General Comments 0
You need to be logged in to leave comments. Login now