##// END OF EJS Templates
templatefilters: declare input type as bytes where appropriate...
Yuya Nishihara -
r37240:08e042f0 default
parent child Browse files
Show More
@@ -173,7 +173,7 b' class requestcontext(object):'
173
173
174 filters = {}
174 filters = {}
175 templatefilter = registrar.templatefilter(filters)
175 templatefilter = registrar.templatefilter(filters)
176 @templatefilter('websub')
176 @templatefilter('websub', intype=bytes)
177 def websubfilter(text):
177 def websubfilter(text):
178 return templatefilters.websub(text, self.websubtable)
178 return templatefilters.websub(text, self.websubtable)
179
179
@@ -40,7 +40,7 b' filters = {}'
40
40
41 templatefilter = registrar.templatefilter(filters)
41 templatefilter = registrar.templatefilter(filters)
42
42
43 @templatefilter('addbreaks')
43 @templatefilter('addbreaks', intype=bytes)
44 def addbreaks(text):
44 def addbreaks(text):
45 """Any text. Add an XHTML "<br />" tag before the end of
45 """Any text. Add an XHTML "<br />" tag before the end of
46 every line except the last.
46 every line except the last.
@@ -90,7 +90,7 b' def age(date, abbrev=False):'
90 return '%s from now' % fmt(t, n, a)
90 return '%s from now' % fmt(t, n, a)
91 return '%s ago' % fmt(t, n, a)
91 return '%s ago' % fmt(t, n, a)
92
92
93 @templatefilter('basename')
93 @templatefilter('basename', intype=bytes)
94 def basename(path):
94 def basename(path):
95 """Any text. Treats the text as a path, and returns the last
95 """Any text. Treats the text as a path, and returns the last
96 component of the path after splitting by the path separator.
96 component of the path after splitting by the path separator.
@@ -103,14 +103,14 b' def count(i):'
103 """List or text. Returns the length as an integer."""
103 """List or text. Returns the length as an integer."""
104 return len(i)
104 return len(i)
105
105
106 @templatefilter('dirname')
106 @templatefilter('dirname', intype=bytes)
107 def dirname(path):
107 def dirname(path):
108 """Any text. Treats the text as a path, and strips the last
108 """Any text. Treats the text as a path, and strips the last
109 component of the path after splitting by the path separator.
109 component of the path after splitting by the path separator.
110 """
110 """
111 return os.path.dirname(path)
111 return os.path.dirname(path)
112
112
113 @templatefilter('domain')
113 @templatefilter('domain', intype=bytes)
114 def domain(author):
114 def domain(author):
115 """Any text. Finds the first string that looks like an email
115 """Any text. Finds the first string that looks like an email
116 address, and extracts just the domain component. Example: ``User
116 address, and extracts just the domain component. Example: ``User
@@ -125,7 +125,7 b' def domain(author):'
125 author = author[:f]
125 author = author[:f]
126 return author
126 return author
127
127
128 @templatefilter('email')
128 @templatefilter('email', intype=bytes)
129 def email(text):
129 def email(text):
130 """Any text. Extracts the first string that looks like an email
130 """Any text. Extracts the first string that looks like an email
131 address. Example: ``User <user@example.com>`` becomes
131 address. Example: ``User <user@example.com>`` becomes
@@ -133,7 +133,7 b' def email(text):'
133 """
133 """
134 return stringutil.email(text)
134 return stringutil.email(text)
135
135
136 @templatefilter('escape')
136 @templatefilter('escape', intype=bytes)
137 def escape(text):
137 def escape(text):
138 """Any text. Replaces the special XML/XHTML characters "&", "<"
138 """Any text. Replaces the special XML/XHTML characters "&", "<"
139 and ">" with XML entities, and filters out NUL characters.
139 and ">" with XML entities, and filters out NUL characters.
@@ -170,17 +170,17 b" def fill(text, width, initindent='', han"
170 width, initindent, hangindent) + rest
170 width, initindent, hangindent) + rest
171 for para, rest in findparas()])
171 for para, rest in findparas()])
172
172
173 @templatefilter('fill68')
173 @templatefilter('fill68', intype=bytes)
174 def fill68(text):
174 def fill68(text):
175 """Any text. Wraps the text to fit in 68 columns."""
175 """Any text. Wraps the text to fit in 68 columns."""
176 return fill(text, 68)
176 return fill(text, 68)
177
177
178 @templatefilter('fill76')
178 @templatefilter('fill76', intype=bytes)
179 def fill76(text):
179 def fill76(text):
180 """Any text. Wraps the text to fit in 76 columns."""
180 """Any text. Wraps the text to fit in 76 columns."""
181 return fill(text, 76)
181 return fill(text, 76)
182
182
183 @templatefilter('firstline')
183 @templatefilter('firstline', intype=bytes)
184 def firstline(text):
184 def firstline(text):
185 """Any text. Returns the first line of text."""
185 """Any text. Returns the first line of text."""
186 try:
186 try:
@@ -188,7 +188,7 b' def firstline(text):'
188 except IndexError:
188 except IndexError:
189 return ''
189 return ''
190
190
191 @templatefilter('hex')
191 @templatefilter('hex', intype=bytes)
192 def hexfilter(text):
192 def hexfilter(text):
193 """Any text. Convert a binary Mercurial node identifier into
193 """Any text. Convert a binary Mercurial node identifier into
194 its long hexadecimal representation.
194 its long hexadecimal representation.
@@ -262,17 +262,17 b' def json(obj, paranoid=True):'
262 else:
262 else:
263 raise TypeError('cannot encode type %s' % obj.__class__.__name__)
263 raise TypeError('cannot encode type %s' % obj.__class__.__name__)
264
264
265 @templatefilter('lower')
265 @templatefilter('lower', intype=bytes)
266 def lower(text):
266 def lower(text):
267 """Any text. Converts the text to lowercase."""
267 """Any text. Converts the text to lowercase."""
268 return encoding.lower(text)
268 return encoding.lower(text)
269
269
270 @templatefilter('nonempty')
270 @templatefilter('nonempty', intype=bytes)
271 def nonempty(text):
271 def nonempty(text):
272 """Any text. Returns '(none)' if the string is empty."""
272 """Any text. Returns '(none)' if the string is empty."""
273 return text or "(none)"
273 return text or "(none)"
274
274
275 @templatefilter('obfuscate')
275 @templatefilter('obfuscate', intype=bytes)
276 def obfuscate(text):
276 def obfuscate(text):
277 """Any text. Returns the input text rendered as a sequence of
277 """Any text. Returns the input text rendered as a sequence of
278 XML entities.
278 XML entities.
@@ -280,7 +280,7 b' def obfuscate(text):'
280 text = unicode(text, pycompat.sysstr(encoding.encoding), r'replace')
280 text = unicode(text, pycompat.sysstr(encoding.encoding), r'replace')
281 return ''.join(['&#%d;' % ord(c) for c in text])
281 return ''.join(['&#%d;' % ord(c) for c in text])
282
282
283 @templatefilter('permissions')
283 @templatefilter('permissions', intype=bytes)
284 def permissions(flags):
284 def permissions(flags):
285 if "l" in flags:
285 if "l" in flags:
286 return "lrwxrwxrwx"
286 return "lrwxrwxrwx"
@@ -288,14 +288,14 b' def permissions(flags):'
288 return "-rwxr-xr-x"
288 return "-rwxr-xr-x"
289 return "-rw-r--r--"
289 return "-rw-r--r--"
290
290
291 @templatefilter('person')
291 @templatefilter('person', intype=bytes)
292 def person(author):
292 def person(author):
293 """Any text. Returns the name before an email address,
293 """Any text. Returns the name before an email address,
294 interpreting it as per RFC 5322.
294 interpreting it as per RFC 5322.
295 """
295 """
296 return stringutil.person(author)
296 return stringutil.person(author)
297
297
298 @templatefilter('revescape')
298 @templatefilter('revescape', intype=bytes)
299 def revescape(text):
299 def revescape(text):
300 """Any text. Escapes all "special" characters, except @.
300 """Any text. Escapes all "special" characters, except @.
301 Forward slashes are escaped twice to prevent web servers from prematurely
301 Forward slashes are escaped twice to prevent web servers from prematurely
@@ -317,14 +317,14 b' def rfc822date(text):'
317 """
317 """
318 return dateutil.datestr(text, "%a, %d %b %Y %H:%M:%S %1%2")
318 return dateutil.datestr(text, "%a, %d %b %Y %H:%M:%S %1%2")
319
319
320 @templatefilter('short')
320 @templatefilter('short', intype=bytes)
321 def short(text):
321 def short(text):
322 """Changeset hash. Returns the short form of a changeset hash,
322 """Changeset hash. Returns the short form of a changeset hash,
323 i.e. a 12 hexadecimal digit string.
323 i.e. a 12 hexadecimal digit string.
324 """
324 """
325 return text[:12]
325 return text[:12]
326
326
327 @templatefilter('shortbisect')
327 @templatefilter('shortbisect', intype=bytes)
328 def shortbisect(label):
328 def shortbisect(label):
329 """Any text. Treats `label` as a bisection status, and
329 """Any text. Treats `label` as a bisection status, and
330 returns a single-character representing the status (G: good, B: bad,
330 returns a single-character representing the status (G: good, B: bad,
@@ -340,17 +340,17 b' def shortdate(text):'
340 """Date. Returns a date like "2006-09-18"."""
340 """Date. Returns a date like "2006-09-18"."""
341 return dateutil.shortdate(text)
341 return dateutil.shortdate(text)
342
342
343 @templatefilter('slashpath')
343 @templatefilter('slashpath', intype=bytes)
344 def slashpath(path):
344 def slashpath(path):
345 """Any text. Replaces the native path separator with slash."""
345 """Any text. Replaces the native path separator with slash."""
346 return util.pconvert(path)
346 return util.pconvert(path)
347
347
348 @templatefilter('splitlines')
348 @templatefilter('splitlines', intype=bytes)
349 def splitlines(text):
349 def splitlines(text):
350 """Any text. Split text into a list of lines."""
350 """Any text. Split text into a list of lines."""
351 return templateutil.hybridlist(text.splitlines(), name='line')
351 return templateutil.hybridlist(text.splitlines(), name='line')
352
352
353 @templatefilter('stringescape')
353 @templatefilter('stringescape', intype=bytes)
354 def stringescape(text):
354 def stringescape(text):
355 return stringutil.escapestr(text)
355 return stringutil.escapestr(text)
356
356
@@ -361,7 +361,7 b' def stringify(thing):'
361 """
361 """
362 return thing # coerced by the intype
362 return thing # coerced by the intype
363
363
364 @templatefilter('stripdir')
364 @templatefilter('stripdir', intype=bytes)
365 def stripdir(text):
365 def stripdir(text):
366 """Treat the text as path and strip a directory level, if
366 """Treat the text as path and strip a directory level, if
367 possible. For example, "foo" and "foo/bar" becomes "foo".
367 possible. For example, "foo" and "foo/bar" becomes "foo".
@@ -372,42 +372,42 b' def stripdir(text):'
372 else:
372 else:
373 return dir
373 return dir
374
374
375 @templatefilter('tabindent')
375 @templatefilter('tabindent', intype=bytes)
376 def tabindent(text):
376 def tabindent(text):
377 """Any text. Returns the text, with every non-empty line
377 """Any text. Returns the text, with every non-empty line
378 except the first starting with a tab character.
378 except the first starting with a tab character.
379 """
379 """
380 return indent(text, '\t')
380 return indent(text, '\t')
381
381
382 @templatefilter('upper')
382 @templatefilter('upper', intype=bytes)
383 def upper(text):
383 def upper(text):
384 """Any text. Converts the text to uppercase."""
384 """Any text. Converts the text to uppercase."""
385 return encoding.upper(text)
385 return encoding.upper(text)
386
386
387 @templatefilter('urlescape')
387 @templatefilter('urlescape', intype=bytes)
388 def urlescape(text):
388 def urlescape(text):
389 """Any text. Escapes all "special" characters. For example,
389 """Any text. Escapes all "special" characters. For example,
390 "foo bar" becomes "foo%20bar".
390 "foo bar" becomes "foo%20bar".
391 """
391 """
392 return urlreq.quote(text)
392 return urlreq.quote(text)
393
393
394 @templatefilter('user')
394 @templatefilter('user', intype=bytes)
395 def userfilter(text):
395 def userfilter(text):
396 """Any text. Returns a short representation of a user name or email
396 """Any text. Returns a short representation of a user name or email
397 address."""
397 address."""
398 return stringutil.shortuser(text)
398 return stringutil.shortuser(text)
399
399
400 @templatefilter('emailuser')
400 @templatefilter('emailuser', intype=bytes)
401 def emailuser(text):
401 def emailuser(text):
402 """Any text. Returns the user portion of an email address."""
402 """Any text. Returns the user portion of an email address."""
403 return stringutil.emailuser(text)
403 return stringutil.emailuser(text)
404
404
405 @templatefilter('utf8')
405 @templatefilter('utf8', intype=bytes)
406 def utf8(text):
406 def utf8(text):
407 """Any text. Converts from the local character encoding to UTF-8."""
407 """Any text. Converts from the local character encoding to UTF-8."""
408 return encoding.fromlocal(text)
408 return encoding.fromlocal(text)
409
409
410 @templatefilter('xmlescape')
410 @templatefilter('xmlescape', intype=bytes)
411 def xmlescape(text):
411 def xmlescape(text):
412 text = (text
412 text = (text
413 .replace('&', '&amp;')
413 .replace('&', '&amp;')
@@ -2284,8 +2284,7 b' Upper/lower filters:'
2284 $ hg log -r0 --template '{author|lower}\n'
2284 $ hg log -r0 --template '{author|lower}\n'
2285 user name <user@hostname>
2285 user name <user@hostname>
2286 $ hg log -r0 --template '{date|upper}\n'
2286 $ hg log -r0 --template '{date|upper}\n'
2287 abort: template filter 'upper' is not compatible with keyword 'date'
2287 1000000.00
2288 [255]
2289
2288
2290 Add a commit that does all possible modifications at once
2289 Add a commit that does all possible modifications at once
2291
2290
@@ -2797,11 +2796,12 b' Error on syntax:'
2797 hg: parse error: missing argument
2796 hg: parse error: missing argument
2798 [255]
2797 [255]
2799
2798
2800 Behind the scenes, this will throw TypeError
2799 Behind the scenes, this would throw TypeError without intype=bytes
2801
2800
2802 $ hg log -l 3 --template '{date|obfuscate}\n'
2801 $ hg log -l 3 --template '{date|obfuscate}\n'
2803 abort: template filter 'obfuscate' is not compatible with keyword 'date'
2802 &#48;&#46;&#48;&#48;
2804 [255]
2803 &#48;&#46;&#48;&#48;
2804 &#49;&#53;&#55;&#55;&#56;&#55;&#50;&#56;&#54;&#48;&#46;&#48;&#48;
2805
2805
2806 Behind the scenes, this will throw a ValueError
2806 Behind the scenes, this will throw a ValueError
2807
2807
@@ -2809,11 +2809,12 b' Behind the scenes, this will throw a Val'
2809 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2809 abort: template filter 'shortdate' is not compatible with keyword 'desc'
2810 [255]
2810 [255]
2811
2811
2812 Behind the scenes, this will throw AttributeError
2812 Behind the scenes, this would throw AttributeError without intype=bytes
2813
2813
2814 $ hg log -l 3 --template 'line: {date|escape}\n'
2814 $ hg log -l 3 --template 'line: {date|escape}\n'
2815 abort: template filter 'escape' is not compatible with keyword 'date'
2815 line: 0.00
2816 [255]
2816 line: 0.00
2817 line: 1577872860.00
2817
2818
2818 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2819 $ hg log -l 3 --template 'line: {extras|localdate}\n'
2819 hg: parse error: localdate expects a date information
2820 hg: parse error: localdate expects a date information
@@ -4656,9 +4657,8 b' utf8 filter:'
4656 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
4657 $ HGENCODING=ascii hg log -T "replaced: {'`cat latin1`'|utf8|hex}\n" -l1
4657 abort: decoding near * (glob)
4658 abort: decoding near * (glob)
4658 [255]
4659 [255]
4659 $ hg log -T "invalid type: {rev|utf8}\n" -r0
4660 $ hg log -T "coerced to string: {rev|utf8}\n" -r0
4660 abort: template filter 'utf8' is not compatible with keyword 'rev'
4661 coerced to string: 0
4661 [255]
4662
4662
4663 pad width:
4663 pad width:
4664
4664
General Comments 0
You need to be logged in to leave comments. Login now