Ticket #14181: t14181-rc1.diff

File t14181-rc1.diff, 15.3 KB (added by russellm, 4 years ago)

Slightly cleaned up patch, ready for trunk

  • django/contrib/gis/templates/gis/google/google-map.js

    diff -r 81ec3f7d0426 django/contrib/gis/templates/gis/google/google-map.js
    a b  
     1{% load l10n %}
    12{% autoescape off %}
    2 {% block vars %}var geodjango = {};{% for icon in icons %}
    3 var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON);
     3{% localize off %}
     4{% block vars %}var geodjango = {};{% for icon in icons %}
     5var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON);
    46{% if icon.image %}{{ icon.varname }}.image = "{{ icon.image }}";{% endif %}
    57{% if icon.shadow %}{{ icon.varname }}.shadow = "{{ icon.shadow }}";{% endif %} {% if icon.shadowsize %}{{ icon.varname }}.shadowSize = new GSize({{ icon.shadowsize.0 }}, {{ icon.shadowsize.1 }});{% endif %}
    68{% if icon.iconanchor %}{{ icon.varname }}.iconAnchor = new GPoint({{ icon.iconanchor.0 }}, {{ icon.iconanchor.1 }});{% endif %} {% if icon.iconsize %}{{ icon.varname }}.iconSize = new GSize({{ icon.iconsize.0 }}, {{ icon.iconsize.1 }});{% endif %}
     
    3234    alert("Sorry, the Google Maps API is not compatible with this browser.");
    3335  }
    3436}
    35 {% endblock load %}{% endblock functions %}{% endautoescape %}
     37{% endblock load %}{% endblock functions %}{% endlocalize %}{% endautoescape %}
  • django/template/__init__.py

    diff -r 81ec3f7d0426 django/template/__init__.py
    a b  
    825825    means escaping, if required, and conversion to a unicode object. If value
    826826    is a string, it is expected to have already been translated.
    827827    """
    828     value = localize(value)
     828    value = localize(value, use_l10n=context.use_l10n)
    829829    value = force_unicode(value)
    830830    if (context.autoescape and not isinstance(value, SafeData)) or isinstance(value, EscapeData):
    831831        return escape(value)
  • django/template/context.py

    diff -r 81ec3f7d0426 django/template/context.py
    a b  
    6666
    6767class Context(BaseContext):
    6868    "A stack container for variable context"
    69     def __init__(self, dict_=None, autoescape=True, current_app=None):
     69    def __init__(self, dict_=None, autoescape=True, current_app=None, use_l10n=None):
    7070        self.autoescape = autoescape
     71        self.use_l10n = use_l10n
    7172        self.current_app = current_app
    7273        self.render_context = RenderContext()
    7374        super(Context, self).__init__(dict_)
     
    139140    Additional processors can be specified as a list of callables
    140141    using the "processors" keyword argument.
    141142    """
    142     def __init__(self, request, dict=None, processors=None, current_app=None):
    143         Context.__init__(self, dict, current_app=current_app)
     143    def __init__(self, request, dict=None, processors=None, current_app=None, use_l10n=None):
     144        Context.__init__(self, dict, current_app=current_app, use_l10n=use_l10n)
    144145        if processors is None:
    145146            processors = ()
    146147        else:
  • django/template/debug.py

    diff -r 81ec3f7d0426 django/template/debug.py
    a b  
     1from django.conf import settings
    12from django.template import Lexer, Parser, tag_re, NodeList, VariableNode, TemplateSyntaxError
    23from django.utils.encoding import force_unicode
    34from django.utils.html import escape
     
    8788    def render(self, context):
    8889        try:
    8990            output = self.filter_expression.resolve(context)
    90             output = localize(output)
     91            output = localize(value, use_l10n=use_l10n)
    9192            output = force_unicode(output)
    9293        except TemplateSyntaxError, e:
    9394            if not hasattr(e, 'source'):
  • new file django/templatetags/l10n.py

    diff -r 81ec3f7d0426 django/templatetags/l10n.py
    - +  
     1from django.conf import settings
     2from django.template import Node
     3from django.template import TemplateSyntaxError, Library
     4from django.utils import formats
     5from django.utils.encoding import force_unicode
     6
     7
     8register = Library()
     9
     10def localize(value):
     11    """
     12    Forces a value to be rendered as a localized value,
     13    regardless of the value of ``settings.USE_L10N``.
     14    """
     15    return force_unicode(formats.localize(value, use_l10n=True))
     16localize.is_safe = False
     17
     18def unlocalize(value):
     19    """
     20    Forces a value to be rendered as a non-localized value,
     21    regardless of the value of ``settings.USE_L10N``.
     22    """
     23    return force_unicode(value)
     24unlocalize.is_safe = False
     25
     26class LocalizeNode(Node):
     27    def __init__(self, nodelist, use_l10n):
     28        self.nodelist = nodelist
     29        self.use_l10n = use_l10n
     30
     31    def __repr__(self):
     32        return "<LocalizeNode>"
     33
     34    def render(self, context):
     35        old_setting = context.use_l10n
     36        context.use_l10n = self.use_l10n
     37        output = self.nodelist.render(context)
     38        context.use_l10n = old_setting
     39        return output
     40
     41@register.tag('localize')
     42def localize_tag(parser, token):
     43    """
     44    Forces or prevents localization of values, regardless of the value of
     45    `settings.USE_L10N`.
     46
     47    Sample usage::
     48
     49        {% localize off %}
     50            var pi = {{ 3.1415 }};
     51        {% endlocalize %}
     52
     53    """
     54    use_l10n = None
     55    bits = list(token.split_contents())
     56    if len(bits) == 1:
     57        use_l10n = True
     58    elif len(bits) > 2 or bits[1] not in ('on', 'off'):
     59        raise TemplateSyntaxError("%r argument should be 'on' or 'off'" % bits[0])
     60    else:
     61        use_l10n = bits[1] == 'on'
     62    nodelist = parser.parse(('endlocalize',))
     63    parser.delete_first_token()
     64    return LocalizeNode(nodelist, use_l10n)
     65
     66register.filter(localize)
     67register.filter(unlocalize)
  • django/utils/formats.py

    diff -r 81ec3f7d0426 django/utils/formats.py
    a b  
    4141        modules.reverse()
    4242    return modules
    4343
    44 def get_format(format_type, lang=None):
     44def get_format(format_type, lang=None, use_l10n=None):
    4545    """
    4646    For a specific format type, returns the format for the current
    4747    language (locale), defaults to the format in the settings.
    4848    format_type is the name of the format, e.g. 'DATE_FORMAT'
     49
     50    If use_l10n is provided and is not None, that will force the value to
     51    be localized (or not), overriding the value of settings.USE_L10N.
    4952    """
    5053    format_type = smart_str(format_type)
    51     if settings.USE_L10N:
     54    if use_l10n or (use_l10n is None and settings.USE_L10N):
    5255        if lang is None:
    5356            lang = get_language()
    5457        cache_key = (format_type, lang)
     
    6568            _format_cache[cache_key] = None
    6669    return getattr(settings, format_type)
    6770
    68 def date_format(value, format=None):
     71def date_format(value, format=None, use_l10n=None):
    6972    """
    7073    Formats a datetime.date or datetime.datetime object using a
    7174    localizable format
     75
     76    If use_l10n is provided and is not None, that will force the value to
     77    be localized (or not), overriding the value of settings.USE_L10N.
    7278    """
    73     return dateformat.format(value, get_format(format or 'DATE_FORMAT'))
     79    return dateformat.format(value, get_format(format or 'DATE_FORMAT', use_l10n=use_l10n))
    7480
    75 def time_format(value, format=None):
     81def time_format(value, format=None, use_l10n=None):
    7682    """
    7783    Formats a datetime.time object using a localizable format
     84
     85    If use_l10n is provided and is not None, that will force the value to
     86    be localized (or not), overriding the value of settings.USE_L10N.
    7887    """
    79     return dateformat.time_format(value, get_format(format or 'TIME_FORMAT'))
     88    return dateformat.time_format(value, get_format(format or 'TIME_FORMAT', use_l10n=use_l10n))
    8089
    81 def number_format(value, decimal_pos=None):
     90def number_format(value, decimal_pos=None, use_l10n=None):
    8291    """
    8392    Formats a numeric value using localization settings
     93
     94    If use_l10n is provided and is not None, that will force the value to
     95    be localized (or not), overriding the value of settings.USE_L10N.
    8496    """
    85     if settings.USE_L10N:
     97    if use_l10n or (use_l10n is None and settings.USE_L10N):
    8698        lang = get_language()
    8799    else:
    88100        lang = None
    89101    return numberformat.format(
    90102        value,
    91         get_format('DECIMAL_SEPARATOR', lang),
     103        get_format('DECIMAL_SEPARATOR', lang, use_l10n=use_l10n),
    92104        decimal_pos,
    93         get_format('NUMBER_GROUPING', lang),
    94         get_format('THOUSAND_SEPARATOR', lang),
     105        get_format('NUMBER_GROUPING', lang, use_l10n=use_l10n),
     106        get_format('THOUSAND_SEPARATOR', lang, use_l10n=use_l10n),
    95107    )
    96108
    97 def localize(value):
     109def localize(value, use_l10n=None):
    98110    """
    99111    Checks if value is a localizable type (date, number...) and returns it
    100     formatted as a string using current locale format
     112    formatted as a string using current locale format.
     113
     114    If use_l10n is provided and is not None, that will force the value to
     115    be localized (or not), overriding the value of settings.USE_L10N.
    101116    """
    102117    if isinstance(value, (decimal.Decimal, float, int, long)):
    103         return number_format(value)
     118        return number_format(value, use_l10n=use_l10n)
    104119    elif isinstance(value, datetime.datetime):
    105         return date_format(value, 'DATETIME_FORMAT')
     120        return date_format(value, 'DATETIME_FORMAT', use_l10n=use_l10n)
    106121    elif isinstance(value, datetime.date):
    107         return date_format(value)
     122        return date_format(value, use_l10n=use_l10n)
    108123    elif isinstance(value, datetime.time):
    109         return time_format(value, 'TIME_FORMAT')
     124        return time_format(value, 'TIME_FORMAT', use_l10n=use_l10n)
    110125    else:
    111126        return value
    112127
  • docs/ref/templates/builtins.txt

    diff -r 81ec3f7d0426 docs/ref/templates/builtins.txt
    a b  
    21132113above because you don't need to add any application to the ``INSTALLED_APPS``
    21142114setting but rather set :setting:`USE_I18N` to True, then loading it with
    21152115``{% load i18n %}``. See :ref:`specifying-translation-strings-in-template-code`.
     2116
     2117l10n
     2118~~~~
     2119
     2120Provides a couple of templatetags that allow control over the localization of
     2121values in Django templates. It is slightly different from the libraries described
     2122above because you don't need to add any application to the ``INSTALLED_APPS``;
     2123you only need to load the library using ``{% load l10n %}``. See
     2124:ref:`topic-l10n-templates`.
  • docs/topics/i18n/localization.txt

    diff -r 81ec3f7d0426 docs/topics/i18n/localization.txt
    a b  
    22Localization
    33============
    44
    5 This document covers two localization-related topics: `Creating language
    6 files`_ and `locale aware date, time and numbers input/output in forms`_
     5This document covers three localization-related topics: `Creating language
     6files`_ , `locale aware date, time and numbers input/output in forms`_,
     7and `controlling localization in templates`_.
    78
    89.. _`Creating language files`: how-to-create-language-files_
    910.. _`locale aware date, time and numbers input/output in forms`: format-localization_
     11.. _`controlling localization in templates`: topic-l10n-templates
    1012
    1113.. seealso::
    1214
     
    315317
    316318to use a space as a thousand separator, instead of the default for English,
    317319a comma.
     320
     321.. topic-l10n-templates:
     322
     323Controlling localization in templates
     324=====================================
     325
     326When you have enabled localization using :setting:`USE_L10N`, Django
     327will try to use a locale specific format whenever it outputs a value
     328in a template.
     329
     330However, it may not always be appropriate to use localized values --
     331for example, if you're outputting Javascript or XML that is designed
     332to be machine-readable, you will always want unlocalized values. You
     333may also want to use localization in selected templates, rather than
     334using localization everywhere.
     335
     336To allow for fine control over the use of localization, Django
     337provides a the ``l10n`` template library that contains the following
     338tags and filters.
     339
     340Template tags
     341-------------
     342
     343.. templatetag:: localize
     344
     345localize
     346~~~~~~~~
     347
     348.. versionadded:: 1.3
     349
     350Enables or disables localization of template variables in the
     351contained block.
     352
     353This tag allows a more fine grained control of localization than
     354:setting:`USE_L10N`.
     355
     356To activate or deactivate localization for a template block, use::
     357
     358    {% localize on %}
     359        {{ value }}
     360    {% endlocalize %}
     361
     362    {% localize off %}
     363        {{ value }}
     364    {% endlocalize %}
     365
     366.. note::
     367
     368    The value of :setting:`USE_L10N` is not respected inside of a
     369    `{% localize %}` block.
     370
     371See :tfilter:`localized` and :tfilter:`unlocalized` for a template filter that will
     372do the same job on a per-variable basis.
     373
     374Template filters
     375----------------
     376
     377.. templatefilter:: localize
     378
     379localize
     380~~~~~~~~
     381
     382.. versionadded:: 1.3
     383
     384Forces localization of a single value.
     385
     386For example::
     387
     388    {{ value|localize }}
     389
     390To disable localization on a single value, use :tfilter:`unlocalize`. To control
     391localization over a large section of a template, use the :ttag:`localize` template
     392tag.
     393
     394
     395.. templatefilter:: unlocalize
     396
     397unlocalize
     398~~~~~~~~~~
     399
     400.. versionadded:: 1.3
     401
     402Forces a single value to be printed without localization.
     403
     404For example::
     405
     406    {{ value|unlocalize }}
     407
     408To force localization of a single value, use :tfilter:`localize`. To
     409control localization over a large section of a template, use the
     410:ttag:`localize` template tag.
  • tests/regressiontests/i18n/tests.py

    diff -r 81ec3f7d0426 tests/regressiontests/i18n/tests.py
    a b  
    453453            settings.FORMAT_MODULE_PATH = old_format_module_path
    454454            deactivate()
    455455
     456    def test_localize_templatetag_and_filter(self):
     457        """
     458        Tests the {% localize %} templatetag
     459        """
     460        context = Context({'value': 3.14 })
     461        template1 = Template("{% load l10n %}{% localize %}{{ value }}{% endlocalize %};{% localize on %}{{ value }}{% endlocalize %}")
     462        template2 = Template("{% load l10n %}{{ value }};{% localize off %}{{ value }};{% endlocalize %}{{ value }}")
     463        template3 = Template('{% load l10n %}{{ value }};{{ value|unlocalize }}')
     464        template4 = Template('{% load l10n %}{{ value }};{{ value|localize }}')
     465        output1 = '3,14;3,14'
     466        output2 = '3,14;3.14;3,14'
     467        output3 = '3,14;3.14'
     468        output4 = '3.14;3,14'
     469        old_localize = settings.USE_L10N
     470        try:
     471            activate('de')
     472            settings.USE_L10N = False
     473            self.assertEqual(template1.render(context), output1)
     474            self.assertEqual(template4.render(context), output4)
     475            settings.USE_L10N = True
     476            self.assertEqual(template1.render(context), output1)
     477            self.assertEqual(template2.render(context), output2)
     478            self.assertEqual(template3.render(context), output3)
     479        finally:
     480            deactivate()
     481            settings.USE_L10N = old_localize
     482
    456483class MiscTests(TestCase):
    457484
    458485    def test_parse_spec_http_header(self):
Back to Top