Ticket #14057: 14057-context-parameter-2.diff
File 14057-context-parameter-2.diff, 11.5 KB (added by , 14 years ago) |
---|
-
django/utils/html.py
47 47 """Converts newlines into <p> and <br />s.""" 48 48 value = re.sub(r'\r\n|\r|\n', '\n', force_unicode(value)) # normalize newlines 49 49 paras = re.split('\n{2,}', value) 50 _escape = callable(autoescape) and autoescape or escape 50 51 if autoescape: 51 paras = [u'<p>%s</p>' % escape(p).replace('\n', '<br />') for p in paras]52 paras = [u'<p>%s</p>' % _escape(p).replace('\n', '<br />') for p in paras] 52 53 else: 53 54 paras = [u'<p>%s</p>' % p.replace('\n', '<br />') for p in paras] 54 55 return u'\n\n'.join(paras) … … 91 92 92 93 If autoescape is True, the link text and URLs will get autoescaped. 93 94 """ 95 _escape = callable(autoescape) and autoescape or escape 94 96 trim_url = lambda x, limit=trim_url_limit: limit is not None and (len(x) > limit and ('%s...' % x[:max(0, limit - 3)])) or x 95 97 safe_input = isinstance(text, SafeData) 96 98 words = word_split_re.split(force_unicode(text)) … … 116 118 if url: 117 119 trimmed = trim_url(middle) 118 120 if autoescape and not safe_input: 119 lead, trail = escape(lead),escape(trail)120 url, trimmed = escape(url),escape(trimmed)121 lead, trail = _escape(lead), _escape(trail) 122 url, trimmed = _escape(url), _escape(trimmed) 121 123 middle = '<a href="%s"%s>%s</a>' % (url, nofollow_attr, trimmed) 122 124 words[i] = mark_safe('%s%s%s' % (lead, middle, trail)) 123 125 else: 124 126 if safe_input: 125 127 words[i] = mark_safe(word) 126 128 elif autoescape: 127 words[i] = escape(word)129 words[i] = _escape(word) 128 130 elif safe_input: 129 131 words[i] = mark_safe(word) 130 132 elif autoescape: 131 words[i] = escape(word)133 words[i] = _escape(word) 132 134 return u''.join(words) 133 135 urlize = allow_lazy(urlize, unicode) 134 136 -
django/utils/safestring.py
117 117 return EscapeUnicode(s) 118 118 return EscapeString(str(s)) 119 119 120 def conditional_custom_escape(escape_function): 121 """ Return a new function that conditionally escapes its input using the 122 given escape function. 123 """ 124 def _escape(value): 125 if isinstance(value, SafeData): 126 return value 127 else: 128 return escape_function(value) 129 for attr in ('autoescape_context', 'safe_filters'): 130 if hasattr(escape_function, attr): 131 setattr(_escape, attr, getattr(escape_function, attr)) 132 return _escape 133 -
django/template/defaultfilters.py
32 32 if args: 33 33 args = list(args) 34 34 args[0] = force_unicode(args[0]) 35 if isinstance(args[0], SafeData) and getattr(func, 'is_safe', False):36 return mark_safe(func(*args, **kwargs))37 35 return func(*args, **kwargs) 38 36 39 37 # Include a reference to the real function (used to check original … … 163 161 return input_val 164 162 165 163 if not m and p < 0: 166 return mark_safe(formats.number_format(u'%d' % (int(d)), 0))164 return formats.number_format(u'%d' % (int(d)), 0) 167 165 168 166 if p == 0: 169 167 exp = Decimal(1) 170 168 else: 171 169 exp = Decimal('1.0') / (Decimal(10) ** abs(p)) 172 170 try: 173 return mark_safe(formats.number_format(u'%s' % str(d.quantize(exp, ROUND_HALF_UP)), abs(p)))171 return formats.number_format(u'%s' % str(d.quantize(exp, ROUND_HALF_UP)), abs(p)) 174 172 except InvalidOperation: 175 173 return input_val 176 174 floatformat.is_safe = True … … 183 181 184 182 def linenumbers(value, autoescape=None): 185 183 """Displays text with line numbers.""" 186 from django.utils.html import escape 184 if callable(autoescape): 185 _escape = autoescape 186 else: 187 from django.utils.html import escape as _escape 187 188 lines = value.split(u'\n') 188 189 # Find the maximum width of the line count, for use with zero padding 189 190 # string format command … … 193 194 lines[i] = (u"%0" + width + u"d. %s") % (i + 1, line) 194 195 else: 195 196 for i, line in enumerate(lines): 196 lines[i] = (u"%0" + width + u"d. %s") % (i + 1, escape(line))197 lines[i] = (u"%0" + width + u"d. %s") % (i + 1, _escape(line)) 197 198 return mark_safe(u'\n'.join(lines)) 198 199 linenumbers.is_safe = True 199 200 linenumbers.needs_autoescape = True … … 224 225 import unicodedata 225 226 value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') 226 227 value = unicode(re.sub('[^\w\s-]', '', value).strip().lower()) 227 return mark_safe(re.sub('[-\s]+', '-', value))228 return re.sub('[-\s]+', '-', value) 228 229 slugify.is_safe = True 229 230 slugify = stringfilter(slugify) 230 231 … … 373 374 center.is_safe = True 374 375 center = stringfilter(center) 375 376 376 def cut(value, arg ):377 def cut(value, arg, autoescape=None): 377 378 """ 378 379 Removes all values of arg from the given string. 379 380 """ 380 381 safe = isinstance(value, SafeData) 381 382 value = value.replace(arg, u'') 382 if safe and arg != ';' :383 if safe and arg != ';' and not callable(autoescape): 383 384 return mark_safe(value) 384 385 return value 385 386 cut = stringfilter(cut) 387 cut.needs_autoescape = True 386 388 387 389 ################### 388 390 # HTML STRINGS # … … 397 399 escape.is_safe = True 398 400 escape = stringfilter(escape) 399 401 400 def force_escape(value ):402 def force_escape(value, autoescape=None): 401 403 """ 402 404 Escapes a string's HTML. This returns a new string containing the escaped 403 405 characters (as opposed to "escape", which marks the content for later 404 406 possible escaping). 405 407 """ 406 from django.utils.html import escape 407 return mark_safe(escape(value)) 408 if callable(autoescape): 409 return mark_safe(autoescape(value)) 410 else: 411 from django.utils.html import escape 412 return mark_safe(_escape(value)) 408 413 force_escape = stringfilter(force_escape) 409 414 force_escape.is_safe = True 415 force_escape.needs_autoescape = True 410 416 411 417 def linebreaks(value, autoescape=None): 412 418 """ … … 415 421 followed by a blank line becomes a paragraph break (``</p>``). 416 422 """ 417 423 from django.utils.html import linebreaks 418 autoescape = autoescape and not isinstance(value, SafeData)424 autoescape = not isinstance(value, SafeData) and autoescape 419 425 return mark_safe(linebreaks(value, autoescape)) 420 426 linebreaks.is_safe = True 421 427 linebreaks.needs_autoescape = True … … 427 433 (``<br />``). 428 434 """ 429 435 if autoescape and not isinstance(value, SafeData): 430 from django.utils.html import escape 431 value = escape(value) 436 if callable(autoescape): 437 value = autoescape(value) 438 else: 439 from django.utils.html import escape 440 value = escape(value) 432 441 return mark_safe(value.replace('\n', '<br />')) 433 442 linebreaksbr.is_safe = True 434 443 linebreaksbr.needs_autoescape = True … … 510 519 Joins a list with a string, like Python's ``str.join(list)``. 511 520 """ 512 521 value = map(force_unicode, value) 522 _escape = callable(autoescape) and autoescape.conditional or conditional_escape 513 523 if autoescape: 514 value = [ conditional_escape(v) for v in value]524 value = [_escape(v) for v in value] 515 525 try: 516 data = conditional_escape(arg).join(value)526 data = _escape(arg).join(value) 517 527 except AttributeError: # fail silently but nicely 518 528 return value 519 529 return mark_safe(data) … … 591 601 </ul> 592 602 </li> 593 603 """ 594 if autoescape: 604 if callable(autoescape): 605 escaper = autoescape.conditional 606 elif autoescape: 595 607 from django.utils.html import conditional_escape 596 608 escaper = conditional_escape 597 609 else: -
django/template/__init__.py
566 566 obj = settings.TEMPLATE_STRING_IF_INVALID 567 567 else: 568 568 obj = self.var 569 570 # Custom autoescape functions can define a context other than html 571 # to prevent html functions from marking output as safe 572 ae_context = getattr(context.autoescape, 'autoescape_context', 'html') 573 # Custom autoescape functions can define a list of safe filter names 574 ae_safe_filters = getattr(context.autoescape, 'safe_filters', set()) 575 569 576 for func, args in self.filters: 577 func_ae_context = getattr(func, 'autoescape_context', 'html') 570 578 arg_vals = [] 571 579 for lookup, arg in args: 572 580 if not lookup: 573 581 arg_vals.append(mark_safe(arg)) 574 582 else: 575 583 arg_vals.append(arg.resolve(context)) 584 585 576 586 if getattr(func, 'needs_autoescape', False): 577 587 new_obj = func(obj, autoescape=context.autoescape, *arg_vals) 578 588 else: 579 589 new_obj = func(obj, *arg_vals) 580 if getattr(func, 'is_safe', False) and isinstance(obj, SafeData): 590 if (getattr(func, 'is_safe', False) and isinstance(obj, SafeData) 591 and (ae_context == func_ae_context or func.__name__ in ae_safe_filters)): 581 592 obj = mark_safe(new_obj) 582 593 elif isinstance(obj, EscapeData): 583 594 obj = mark_for_escaping(new_obj) … … 828 839 value = localize(value, use_l10n=context.use_l10n) 829 840 value = force_unicode(value) 830 841 if (context.autoescape and not isinstance(value, SafeData)) or isinstance(value, EscapeData): 831 return escape(value) 842 if callable(context.autoescape): 843 return context.autoescape(value) 844 else: 845 return escape(value) 832 846 else: 833 847 return value 834 848 -
django/template/context.py
1 1 from django.core.exceptions import ImproperlyConfigured 2 2 from django.utils.importlib import import_module 3 from django.utils.safestring import conditional_custom_escape 3 4 4 5 # Cache of actual callables. 5 6 _standard_context_processors = None … … 67 68 class Context(BaseContext): 68 69 "A stack container for variable context" 69 70 def __init__(self, dict_=None, autoescape=True, current_app=None, use_l10n=None): 71 if callable(autoescape): 72 autoescape.conditional = conditional_custom_escape(autoescape) 70 73 self.autoescape = autoescape 71 74 self.use_l10n = use_l10n 72 75 self.current_app = current_app -
django/template/debug.py
97 97 except UnicodeDecodeError: 98 98 return '' 99 99 if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData): 100 return escape(output) 100 if callable(context.autoescape): 101 return context.autoescape(output) 102 else: 103 return escape(output) 101 104 else: 102 105 return output