diff --git a/django/contrib/gis/templates/gis/google/google-map.js b/django/contrib/gis/templates/gis/google/google-map.js
index 06f11e3..a8bcba5 100644
|
a
|
b
|
|
| 1 | 1 | {% autoescape off %} |
| | 2 | {% localize off %} |
| 2 | 3 | {% block vars %}var geodjango = {};{% for icon in icons %} |
| 3 | 4 | var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON); |
| 4 | 5 | {% if icon.image %}{{ icon.varname }}.image = "{{ icon.image }}";{% endif %} |
| … |
… |
var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON);
|
| 32 | 33 | alert("Sorry, the Google Maps API is not compatible with this browser."); |
| 33 | 34 | } |
| 34 | 35 | } |
| 35 | | {% endblock load %}{% endblock functions %}{% endautoescape %} |
| | 36 | {% endblock load %}{% endblock functions %}{% endlocalize %}{% endautoescape %} |
diff --git a/django/template/__init__.py b/django/template/__init__.py
index c316786..0edcbe2 100644
|
a
|
b
|
from django.utils.itercompat import is_iterable
|
| 59 | 59 | from django.utils.functional import curry, Promise |
| 60 | 60 | from django.utils.text import smart_split, unescape_string_literal, get_text_list |
| 61 | 61 | from django.utils.encoding import smart_unicode, force_unicode, smart_str |
| 62 | | from django.utils.translation import ugettext as _ |
| | 62 | from django.utils.translation import ugettext as _, get_language, activate |
| 63 | 63 | from django.utils.safestring import SafeData, EscapeData, mark_safe, mark_for_escaping |
| 64 | 64 | from django.utils.formats import localize |
| 65 | 65 | from django.utils.html import escape |
| … |
… |
class TextNode(Node):
|
| 819 | 819 | def render(self, context): |
| 820 | 820 | return self.s |
| 821 | 821 | |
| | 822 | def _localize_from_context(value, context): |
| | 823 | """ |
| | 824 | Checks if context requires special localization and applies localization |
| | 825 | if necessary |
| | 826 | """ |
| | 827 | locale = context.get('_locale', None) |
| | 828 | if locale is not None: |
| | 829 | if not isinstance(locale, bool): |
| | 830 | old_lang = get_language() |
| | 831 | activate(locale) |
| | 832 | value = localize(value, force=True) |
| | 833 | elif locale: |
| | 834 | value = localize(value, force=locale) |
| | 835 | else: |
| | 836 | value = localize(value) |
| | 837 | return value |
| | 838 | |
| 822 | 839 | def _render_value_in_context(value, context): |
| 823 | 840 | """ |
| 824 | 841 | Converts any value to a string to become part of a rendered template. This |
| 825 | 842 | means escaping, if required, and conversion to a unicode object. If value |
| 826 | 843 | is a string, it is expected to have already been translated. |
| 827 | 844 | """ |
| 828 | | value = localize(value) |
| | 845 | value = _localize_from_context(value, context) |
| 829 | 846 | value = force_unicode(value) |
| 830 | 847 | if (context.autoescape and not isinstance(value, SafeData)) or isinstance(value, EscapeData): |
| 831 | 848 | return escape(value) |
diff --git a/django/template/debug.py b/django/template/debug.py
index c21fb50..0ba4e02 100644
|
a
|
b
|
|
| 1 | | from django.template import Lexer, Parser, tag_re, NodeList, VariableNode, TemplateSyntaxError |
| | 1 | from django.template import Lexer, Parser, tag_re, NodeList, VariableNode, TemplateSyntaxError, _localize_from_context |
| 2 | 2 | from django.utils.encoding import force_unicode |
| 3 | 3 | from django.utils.html import escape |
| 4 | 4 | from django.utils.safestring import SafeData, EscapeData |
| … |
… |
class DebugVariableNode(VariableNode):
|
| 87 | 87 | def render(self, context): |
| 88 | 88 | try: |
| 89 | 89 | output = self.filter_expression.resolve(context) |
| 90 | | output = localize(output) |
| | 90 | output = _localize_from_context(value, context) |
| 91 | 91 | output = force_unicode(output) |
| 92 | 92 | except TemplateSyntaxError, e: |
| 93 | 93 | if not hasattr(e, 'source'): |
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index 1b07413..c4c347a 100644
|
a
|
b
|
class WithNode(Node):
|
| 433 | 433 | context.pop() |
| 434 | 434 | return output |
| 435 | 435 | |
| | 436 | class LocalizeNode(Node): |
| | 437 | def __init__(self, nodelist, locale): |
| | 438 | self.nodelist = nodelist |
| | 439 | self.locale = locale |
| | 440 | |
| | 441 | def __repr__(self): |
| | 442 | return "<LocalizeNode>" |
| | 443 | |
| | 444 | def render(self, context): |
| | 445 | if isinstance(self.locale, bool): |
| | 446 | context['_locale'] = self.locale |
| | 447 | else: |
| | 448 | context['_locale'] = self.locale.resolve(context) |
| | 449 | output = self.nodelist.render(context) |
| | 450 | del context['_locale'] |
| | 451 | return output |
| | 452 | |
| 436 | 453 | #@register.tag |
| 437 | 454 | def autoescape(parser, token): |
| 438 | 455 | """ |
| … |
… |
def do_with(parser, token):
|
| 1216 | 1233 | parser.delete_first_token() |
| 1217 | 1234 | return WithNode(var, name, nodelist) |
| 1218 | 1235 | do_with = register.tag('with', do_with) |
| | 1236 | |
| | 1237 | @register.tag |
| | 1238 | def localize(parser, token): |
| | 1239 | """ |
| | 1240 | Temporarely deactivates localization inside of this block, e.g. |
| | 1241 | to avoid rendering syntactically incorrect JavaScript code. |
| | 1242 | """ |
| | 1243 | locale = None |
| | 1244 | bits = list(token.split_contents()) |
| | 1245 | if len(bits) == 1: |
| | 1246 | locale = True |
| | 1247 | elif len(bits) > 2: |
| | 1248 | raise TemplateSyntaxError("%r expected argument is on/off or a single locale like de or en-us" % bits[0]) |
| | 1249 | else: |
| | 1250 | if bits[1] == 'off': |
| | 1251 | print "off" |
| | 1252 | locale = False |
| | 1253 | elif bits[1] == 'on': |
| | 1254 | print "on" |
| | 1255 | locale = True |
| | 1256 | else: |
| | 1257 | locale = parser.compile_filter(bits[1]) |
| | 1258 | nodelist = parser.parse(('endlocalize',)) |
| | 1259 | parser.delete_first_token() |
| | 1260 | return LocalizeNode(nodelist, locale) |
diff --git a/django/utils/formats.py b/django/utils/formats.py
index e64cc4e..6f8087d 100644
|
a
|
b
|
def get_format_modules(reverse=False):
|
| 41 | 41 | modules.reverse() |
| 42 | 42 | return modules |
| 43 | 43 | |
| 44 | | def get_format(format_type, lang=None): |
| | 44 | def get_format(format_type, lang=None, force=False): |
| 45 | 45 | """ |
| 46 | 46 | For a specific format type, returns the format for the current |
| 47 | 47 | language (locale), defaults to the format in the settings. |
| 48 | | format_type is the name of the format, e.g. 'DATE_FORMAT' |
| | 48 | format_type is the name of the format, e.g. 'DATE_FORMAT'. |
| 49 | 49 | """ |
| 50 | 50 | format_type = smart_str(format_type) |
| 51 | | if settings.USE_L10N: |
| | 51 | if settings.USE_L10N or force: |
| 52 | 52 | if lang is None: |
| 53 | 53 | lang = get_language() |
| 54 | 54 | cache_key = (format_type, lang) |
| … |
… |
def get_format(format_type, lang=None):
|
| 65 | 65 | _format_cache[cache_key] = None |
| 66 | 66 | return getattr(settings, format_type) |
| 67 | 67 | |
| 68 | | def date_format(value, format=None): |
| | 68 | def date_format(value, format=None, force=False): |
| 69 | 69 | """ |
| 70 | 70 | Formats a datetime.date or datetime.datetime object using a |
| 71 | 71 | localizable format |
| 72 | 72 | """ |
| 73 | | return dateformat.format(value, get_format(format or 'DATE_FORMAT')) |
| | 73 | return dateformat.format(value, get_format(format or 'DATE_FORMAT', force=force)) |
| 74 | 74 | |
| 75 | | def time_format(value, format=None): |
| | 75 | def time_format(value, format=None, force=False): |
| 76 | 76 | """ |
| 77 | 77 | Formats a datetime.time object using a localizable format |
| 78 | 78 | """ |
| 79 | | return dateformat.time_format(value, get_format(format or 'TIME_FORMAT')) |
| | 79 | return dateformat.time_format(value, get_format(format or 'TIME_FORMAT', force=force)) |
| 80 | 80 | |
| 81 | | def number_format(value, decimal_pos=None): |
| | 81 | def number_format(value, decimal_pos=None, force=False): |
| 82 | 82 | """ |
| 83 | 83 | Formats a numeric value using localization settings |
| 84 | 84 | """ |
| 85 | | if settings.USE_L10N: |
| | 85 | if settings.USE_L10N or force: |
| 86 | 86 | lang = get_language() |
| 87 | 87 | else: |
| 88 | 88 | lang = None |
| 89 | 89 | return numberformat.format( |
| 90 | 90 | value, |
| 91 | | get_format('DECIMAL_SEPARATOR', lang), |
| | 91 | get_format('DECIMAL_SEPARATOR', lang, force=force), |
| 92 | 92 | decimal_pos, |
| 93 | | get_format('NUMBER_GROUPING', lang), |
| 94 | | get_format('THOUSAND_SEPARATOR', lang), |
| | 93 | get_format('NUMBER_GROUPING', lang, force=force), |
| | 94 | get_format('THOUSAND_SEPARATOR', lang, force=force), |
| 95 | 95 | ) |
| 96 | 96 | |
| 97 | | def localize(value): |
| | 97 | def localize(value, force=False): |
| 98 | 98 | """ |
| 99 | 99 | Checks if value is a localizable type (date, number...) and returns it |
| 100 | 100 | formatted as a string using current locale format |
| | 101 | If force is True, localization is enabled without respecting settings.USE_L10N. |
| 101 | 102 | """ |
| 102 | 103 | if isinstance(value, (decimal.Decimal, float, int, long)): |
| 103 | | return number_format(value) |
| | 104 | return number_format(value, force=force) |
| 104 | 105 | elif isinstance(value, datetime.datetime): |
| 105 | | return date_format(value, 'DATETIME_FORMAT') |
| | 106 | return date_format(value, 'DATETIME_FORMAT', force=force) |
| 106 | 107 | elif isinstance(value, datetime.date): |
| 107 | | return date_format(value) |
| | 108 | return date_format(value, force=force) |
| 108 | 109 | elif isinstance(value, datetime.time): |
| 109 | | return time_format(value, 'TIME_FORMAT') |
| | 110 | return time_format(value, 'TIME_FORMAT', force=force) |
| 110 | 111 | else: |
| 111 | 112 | return value |
| 112 | 113 | |
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
index 70f0ffd..b846b58 100644
|
a
|
b
|
Load a custom template tag set.
|
| 639 | 639 | |
| 640 | 640 | See :doc:`Custom tag and filter libraries </howto/custom-template-tags>` for more information. |
| 641 | 641 | |
| | 642 | .. templatetag:: localize |
| | 643 | |
| | 644 | localize |
| | 645 | ~~~~~ |
| | 646 | |
| | 647 | .. versionadded:: 1.3 |
| | 648 | |
| | 649 | Adjusts localization behavior for contained block. |
| | 650 | |
| | 651 | This tag allows a more fine grained control of localization than |
| | 652 | :setting:`USE_L10N`. |
| | 653 | |
| | 654 | To activate or deactivate localization for a template block, use:: |
| | 655 | |
| | 656 | {% localize on %} |
| | 657 | {{ value }} |
| | 658 | {% endlocalize %} |
| | 659 | |
| | 660 | {% localize off %} |
| | 661 | {{ value }} |
| | 662 | {% endlocalize %} |
| | 663 | |
| | 664 | You can use a different locale than the current one for a template block:: |
| | 665 | |
| | 666 | {% localize "de" %} |
| | 667 | {{ value }} |
| | 668 | {% endlocalize %} |
| | 669 | |
| | 670 | .. note:: |
| | 671 | |
| | 672 | The value of :setting:`USE_L10N` is not respected inside of a |
| | 673 | `{% localize %}` block. |
| | 674 | |
| 642 | 675 | .. templatetag:: now |
| 643 | 676 | |
| 644 | 677 | now |
diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
index 4aa52b6..19e4b6c 100644
|
a
|
b
|
class FormattingTests(TestCase):
|
| 453 | 453 | settings.FORMAT_MODULE_PATH = old_format_module_path |
| 454 | 454 | deactivate() |
| 455 | 455 | |
| | 456 | def test_localize_templatetag(self): |
| | 457 | """ |
| | 458 | Tests the {% noloc %} templatetag |
| | 459 | """ |
| | 460 | context = Context({'value': 3.14 }) |
| | 461 | template1 = Template("{{ value }};{% localize off %}{{ value }};{% endlocalize %}{{ value }}") |
| | 462 | template2 = Template("{% localize %}{{ value }}{% endlocalize %};{% localize on %}{{ value }}{% endlocalize %}") |
| | 463 | template3 = Template('{{ value }};{% localize "de" %}{{ value }}{% endlocalize %}') |
| | 464 | output1 = '3,14;3.14;3,14' |
| | 465 | output2 = '3,14;3,14' |
| | 466 | output3 = '3.14;3,14' |
| | 467 | old_debug = settings.TEMPLATE_DEBUG |
| | 468 | old_localize = settings.USE_L10N |
| | 469 | try: |
| | 470 | for debug in (True, False): |
| | 471 | settings.TEMPLATE_DEBUG = debug |
| | 472 | settings.USE_L10N = False |
| | 473 | self.assertEqual(template3.render(context), output3) |
| | 474 | activate('de') |
| | 475 | self.assertEqual(template2.render(context), output2) |
| | 476 | settings.USE_L10N = True |
| | 477 | self.assertEqual(template1.render(context), output1) |
| | 478 | deactivate() |
| | 479 | finally: |
| | 480 | deactivate() |
| | 481 | settings.TEMPLATE_DEBUG = old_debug |
| | 482 | settings.USE_L10N = old_localize |
| | 483 | |
| 456 | 484 | class MiscTests(TestCase): |
| 457 | 485 | |
| 458 | 486 | def test_parse_spec_http_header(self): |