Ticket #14181: localize-template-tag-2.diff

File localize-template-tag-2.diff, 13.1 KB (added by Benjamin Wohlwend, 13 years ago)

Changes proposed by russellm on django-developers

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

    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  
    11{% autoescape off %}
     2{% localize off %}
    23{% block vars %}var geodjango = {};{% for icon in icons %}
    34var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON);
    45{% if icon.image %}{{ icon.varname }}.image = "{{ icon.image }}";{% endif %}
    var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON);  
    3233    alert("Sorry, the Google Maps API is not compatible with this browser.");
    3334  }
    3435}
    35 {% endblock load %}{% endblock functions %}{% endautoescape %}
     36{% endblock load %}{% endblock functions %}{% endlocalize %}{% endautoescape %}
  • django/template/__init__.py

    diff --git a/django/template/__init__.py b/django/template/__init__.py
    index c316786..ac8f117 100644
    a b class NodeList(list):  
    789789    # extend_nodelist().
    790790    contains_nontext = False
    791791
    792     def render(self, context):
     792    def render(self, context, localization=None):
    793793        bits = []
    794794        for node in self:
    795795            if isinstance(node, Node):
    796                 bits.append(self.render_node(node, context))
     796                bits.append(self.render_node(node, context, localization))
    797797            else:
    798798                bits.append(node)
    799799        return mark_safe(''.join([force_unicode(b) for b in bits]))
    class NodeList(list):  
    805805            nodes.extend(node.get_nodes_by_type(nodetype))
    806806        return nodes
    807807
    808     def render_node(self, node, context):
     808    def render_node(self, node, context, localization=None):
     809        if isinstance(node, VariableNode):
     810            return node.render(context, localization)
    809811        return node.render(context)
    810812
    811813class TextNode(Node):
    class TextNode(Node):  
    819821    def render(self, context):
    820822        return self.s
    821823
    822 def _render_value_in_context(value, context):
     824def _render_value_in_context(value, context, localization=None):
    823825    """
    824826    Converts any value to a string to become part of a rendered template. This
    825827    means escaping, if required, and conversion to a unicode object. If value
    826828    is a string, it is expected to have already been translated.
    827829    """
    828     value = localize(value)
     830    value = localize(value, localization)
    829831    value = force_unicode(value)
    830832    if (context.autoescape and not isinstance(value, SafeData)) or isinstance(value, EscapeData):
    831833        return escape(value)
    class VariableNode(Node):  
    839841    def __repr__(self):
    840842        return "<Variable Node: %s>" % self.filter_expression
    841843
    842     def render(self, context):
     844    def render(self, context, localization):
    843845        try:
    844846            output = self.filter_expression.resolve(context)
    845847        except UnicodeDecodeError:
    846848            # Unicode conversion can fail sometimes for reasons out of our
    847849            # control (e.g. exception rendering). In that case, we fail quietly.
    848850            return ''
    849         return _render_value_in_context(output, context)
     851        return _render_value_in_context(output, context, localization)
    850852
    851853def generic_tag_compiler(params, defaults, name, node_class, parser, token):
    852854    "Returns a template.Node subclass."
  • django/template/debug.py

    diff --git a/django/template/debug.py b/django/template/debug.py
    index c21fb50..be2f3e4 100644
    a b class DebugNodeList(NodeList):  
    8484        return result
    8585
    8686class DebugVariableNode(VariableNode):
    87     def render(self, context):
     87    def render(self, context, localization=None):
    8888        try:
    8989            output = self.filter_expression.resolve(context)
    90             output = localize(output)
     90            output = localize(value, context, localization)
    9191            output = force_unicode(output)
    9292        except TemplateSyntaxError, e:
    9393            if not hasattr(e, 'source'):
  • django/template/defaultfilters.py

    diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py
    index 1500a05..44e71b7 100644
    a b linebreaksbr.is_safe = True  
    434434linebreaksbr.needs_autoescape = True
    435435linebreaksbr = stringfilter(linebreaksbr)
    436436
     437def localize(value, localization='on'):
     438    """
     439    Localizes (or prevents localization) of a value, not respecting
     440    ``settings.USE_L10N``.
     441    """
     442    if localization not in ('on', 'off'):
     443        return value
     444    localization = localization == 'on'
     445    return force_unicode(formats.localize(value, localization))
     446localize.is_safe = False
     447
    437448def safe(value):
    438449    """
    439450    Marks the value as a string that should not be auto-escaped.
    register.filter(linebreaks)  
    922933register.filter(linebreaksbr)
    923934register.filter(linenumbers)
    924935register.filter(ljust)
     936register.filter(localize)
    925937register.filter(lower)
    926938register.filter(make_list)
    927939register.filter(phone2numeric)
  • django/template/defaulttags.py

    diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
    index 1b07413..d0f654d 100644
    a b class WithNode(Node):  
    433433        context.pop()
    434434        return output
    435435
     436class LocalizeNode(Node):
     437    def __init__(self, nodelist, localization):
     438        self.nodelist = nodelist
     439        self.localization = localization
     440
     441    def __repr__(self):
     442        return "<LocalizeNode>"
     443
     444    def render(self, context):
     445        return self.nodelist.render(context, self.localization)
     446
    436447#@register.tag
    437448def autoescape(parser, token):
    438449    """
    def load(parser, token):  
    929940    return LoadNode()
    930941load = register.tag(load)
    931942
     943@register.tag
     944def localize(parser, token):
     945    """
     946    Forces or prevents localization without respect to `settings.USE_L10N`.
     947   
     948    Sample usage::
     949   
     950        {% localize off %}
     951            var pi = {{ 3.1415 }};
     952        {% endlocalize %}
     953       
     954    """
     955    localization = None
     956    bits = list(token.split_contents())
     957    if len(bits) == 1:
     958        localization = True
     959    elif len(bits) > 2 or bits[1] not in ('on', 'off'):
     960        raise TemplateSyntaxError("%r argument should be 'on' or 'off'" % bits[0])
     961    else:
     962        localization = bits[1] == 'on'
     963    nodelist = parser.parse(('endlocalize',))
     964    parser.delete_first_token()
     965    return LocalizeNode(nodelist, localization)
     966
    932967#@register.tag
    933968def now(parser, token):
    934969    """
  • django/utils/formats.py

    diff --git a/django/utils/formats.py b/django/utils/formats.py
    index e64cc4e..9ace738 100644
    a b def get_format_modules(reverse=False):  
    4141        modules.reverse()
    4242    return modules
    4343
    44 def get_format(format_type, lang=None):
     44def get_format(format_type, lang=None, localization=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'
    4949    """
    5050    format_type = smart_str(format_type)
    51     if settings.USE_L10N:
     51    if (localization is None and settings.USE_L10N) or localization:
    5252        if lang is None:
    5353            lang = get_language()
    5454        cache_key = (format_type, lang)
    def get_format(format_type, lang=None):  
    6565            _format_cache[cache_key] = None
    6666    return getattr(settings, format_type)
    6767
    68 def date_format(value, format=None):
     68def date_format(value, format=None, localization=None):
    6969    """
    7070    Formats a datetime.date or datetime.datetime object using a
    7171    localizable format
    7272    """
    73     return dateformat.format(value, get_format(format or 'DATE_FORMAT'))
     73    return dateformat.format(value, get_format(format or 'DATE_FORMAT', localization=localization))
    7474
    75 def time_format(value, format=None):
     75def time_format(value, format=None, localization=None):
    7676    """
    7777    Formats a datetime.time object using a localizable format
    7878    """
    79     return dateformat.time_format(value, get_format(format or 'TIME_FORMAT'))
     79    return dateformat.time_format(value, get_format(format or 'TIME_FORMAT', localization=localization))
    8080
    81 def number_format(value, decimal_pos=None):
     81def number_format(value, decimal_pos=None, localization=None):
    8282    """
    8383    Formats a numeric value using localization settings
    8484    """
    85     if settings.USE_L10N:
     85    if (localization is None and settings.USE_L10N) or localization:
    8686        lang = get_language()
    8787    else:
    8888        lang = None
    8989    return numberformat.format(
    9090        value,
    91         get_format('DECIMAL_SEPARATOR', lang),
     91        get_format('DECIMAL_SEPARATOR', lang, localization),
    9292        decimal_pos,
    93         get_format('NUMBER_GROUPING', lang),
    94         get_format('THOUSAND_SEPARATOR', lang),
     93        get_format('NUMBER_GROUPING', lang, localization),
     94        get_format('THOUSAND_SEPARATOR', lang, localization),
    9595    )
    9696
    97 def localize(value):
     97def localize(value, localization=None):
    9898    """
    9999    Checks if value is a localizable type (date, number...) and returns it
    100     formatted as a string using current locale format
     100    formatted as a string using current locale format.
     101    If the value of `localization` is True or False, localization is enabled or
     102    disabled without respect to `settings.USE_L10N`.
    101103    """
     104    if localization is False: # can't use truth value, None has special meaning
     105        return value
    102106    if isinstance(value, (decimal.Decimal, float, int, long)):
    103         return number_format(value)
     107        return number_format(value, localization=localization)
    104108    elif isinstance(value, datetime.datetime):
    105         return date_format(value, 'DATETIME_FORMAT')
     109        return date_format(value, 'DATETIME_FORMAT', localization)
    106110    elif isinstance(value, datetime.date):
    107         return date_format(value)
     111        return date_format(value, localization=localization)
    108112    elif isinstance(value, datetime.time):
    109         return time_format(value, 'TIME_FORMAT')
     113        return time_format(value, 'TIME_FORMAT', localization)
    110114    else:
    111115        return value
    112116
  • docs/ref/templates/builtins.txt

    diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
    index 70f0ffd..9e86ee3 100644
    a b Load a custom template tag set.  
    639639
    640640See :doc:`Custom tag and filter libraries </howto/custom-template-tags>` for more information.
    641641
     642.. templatetag:: localize
     643
     644localize
     645~~~~~~~~
     646
     647.. versionadded:: 1.3
     648
     649Enables or disables localization for contained block.
     650
     651This tag allows a more fine grained control of localization than
     652:setting:`USE_L10N`.
     653
     654To 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.. note::
     665
     666    The value of :setting:`USE_L10N` is not respected inside of a
     667    `{% localize %}` block.   
     668
     669See :tfilter:`localize` for the analog template filter.
     670
    642671.. templatetag:: now
    643672
    644673now
    For example::  
    15611590
    15621591If ``value`` is ``Django``, the output will be ``"Django    "``.
    15631592
     1593.. templatefilter:: localize
     1594
     1595localize
     1596~~~~~~~~
     1597
     1598.. versionadded:: 1.3
     1599
     1600Localizes (or prevents localization) of a value.
     1601
     1602**Argument:** "on" or "off"
     1603
     1604To prevent a value to be localized when :setting:`USE_L10N` is ``True``::
     1605
     1606    {{ value|localize:"off" }}
     1607   
     1608To force localization of a value::
     1609
     1610    {{ value|localize:"on" }}
     1611   
     1612or a shorthand::
     1613
     1614    {{ value|localize }}
     1615   
     1616See :ttag:`localize` for the analog template tag.
     1617
    15641618.. templatefilter:: lower
    15651619
    15661620lower
  • tests/regressiontests/i18n/tests.py

    diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
    index 4aa52b6..6f8c3de 100644
    a b class FormattingTests(TestCase):  
    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("{% localize %}{{ value }}{% endlocalize %};{% localize on %}{{ value }}{% endlocalize %}")
     462        template2 = Template("{{ value }};{% localize off %}{{ value }};{% endlocalize %}{{ value }}")
     463        template3 = Template('{{ value }};{{ value|localize:"off" }}')
     464        template4 = Template('{{ value }};{{ value|localize }};{{ value|localize:"on" }}')
     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;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