diff --git a/AUTHORS b/AUTHORS
index e1eaded9c3..bc45ce7809 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -501,6 +501,7 @@ answer newbie questions, and generally made Django that much better:
     Joel Watts <joel@joelwatts.com>
     Lakin Wecker <lakin@structuredabstraction.com>
     Chris Wesseling <Chris.Wesseling@cwi.nl>
+    Benjamin Wohlwend <piquadrat@gmail.com>
     James Wheare <django@sparemint.com>
     Mike Wiacek <mjwiacek@google.com>
     Frank Wierzbicki
diff --git a/django/contrib/gis/templates/gis/google/google-map.js b/django/contrib/gis/templates/gis/google/google-map.js
index 06f11e35f3..5c1c8132b9 100644
--- a/django/contrib/gis/templates/gis/google/google-map.js
+++ b/django/contrib/gis/templates/gis/google/google-map.js
@@ -1,6 +1,8 @@
+{% load l10n %}
 {% autoescape off %}
-{% block vars %}var geodjango = {};{% for icon in icons %} 
-var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON); 
+{% localize off %}
+{% block vars %}var geodjango = {};{% for icon in icons %}
+var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON);
 {% if icon.image %}{{ icon.varname }}.image = "{{ icon.image }}";{% endif %}
 {% if icon.shadow %}{{ icon.varname }}.shadow = "{{ icon.shadow }}";{% endif %} {% if icon.shadowsize %}{{ icon.varname }}.shadowSize = new GSize({{ icon.shadowsize.0 }}, {{ icon.shadowsize.1 }});{% endif %}
 {% 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 %}
@@ -32,4 +34,4 @@ var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON);
     alert("Sorry, the Google Maps API is not compatible with this browser.");
   }
 }
-{% endblock load %}{% endblock functions %}{% endautoescape %}
+{% endblock load %}{% endblock functions %}{% endlocalize %}{% endautoescape %}
diff --git a/django/template/__init__.py b/django/template/__init__.py
index c3167861fd..74403584be 100644
--- a/django/template/__init__.py
+++ b/django/template/__init__.py
@@ -825,7 +825,7 @@ def _render_value_in_context(value, context):
     means escaping, if required, and conversion to a unicode object. If value
     is a string, it is expected to have already been translated.
     """
-    value = localize(value)
+    value = localize(value, use_l10n=context.use_l10n)
     value = force_unicode(value)
     if (context.autoescape and not isinstance(value, SafeData)) or isinstance(value, EscapeData):
         return escape(value)
diff --git a/django/template/context.py b/django/template/context.py
index 323c1446b2..a5b417cdd3 100644
--- a/django/template/context.py
+++ b/django/template/context.py
@@ -66,8 +66,9 @@ class BaseContext(object):
 
 class Context(BaseContext):
     "A stack container for variable context"
-    def __init__(self, dict_=None, autoescape=True, current_app=None):
+    def __init__(self, dict_=None, autoescape=True, current_app=None, use_l10n=None):
         self.autoescape = autoescape
+        self.use_l10n = use_l10n
         self.current_app = current_app
         self.render_context = RenderContext()
         super(Context, self).__init__(dict_)
@@ -139,8 +140,8 @@ class RequestContext(Context):
     Additional processors can be specified as a list of callables
     using the "processors" keyword argument.
     """
-    def __init__(self, request, dict=None, processors=None, current_app=None):
-        Context.__init__(self, dict, current_app=current_app)
+    def __init__(self, request, dict=None, processors=None, current_app=None, use_l10n=None):
+        Context.__init__(self, dict, current_app=current_app, use_l10n=use_l10n)
         if processors is None:
             processors = ()
         else:
diff --git a/django/template/debug.py b/django/template/debug.py
index c21fb50b3e..aa42b2b5ca 100644
--- a/django/template/debug.py
+++ b/django/template/debug.py
@@ -1,3 +1,4 @@
+from django.conf import settings
 from django.template import Lexer, Parser, tag_re, NodeList, VariableNode, TemplateSyntaxError
 from django.utils.encoding import force_unicode
 from django.utils.html import escape
@@ -87,7 +88,7 @@ class DebugVariableNode(VariableNode):
     def render(self, context):
         try:
             output = self.filter_expression.resolve(context)
-            output = localize(output)
+            output = localize(value, use_l10n=use_l10n)
             output = force_unicode(output)
         except TemplateSyntaxError, e:
             if not hasattr(e, 'source'):
diff --git a/django/templatetags/l10n.py b/django/templatetags/l10n.py
new file mode 100644
index 0000000000..5191e6936d
--- /dev/null
+++ b/django/templatetags/l10n.py
@@ -0,0 +1,67 @@
+from django.conf import settings
+from django.template import Node
+from django.template import TemplateSyntaxError, Library
+from django.utils import formats
+from django.utils.encoding import force_unicode
+
+
+register = Library()
+
+def localize(value):
+    """
+    Forces a value to be rendered as a localized value,
+    regardless of the value of ``settings.USE_L10N``.
+    """
+    return force_unicode(formats.localize(value, use_l10n=True))
+localize.is_safe = False
+
+def unlocalize(value):
+    """
+    Forces a value to be rendered as a non-localized value,
+    regardless of the value of ``settings.USE_L10N``.
+    """
+    return force_unicode(value)
+unlocalize.is_safe = False
+
+class LocalizeNode(Node):
+    def __init__(self, nodelist, use_l10n):
+        self.nodelist = nodelist
+        self.use_l10n = use_l10n
+
+    def __repr__(self):
+        return "<LocalizeNode>"
+
+    def render(self, context):
+        old_setting = context.use_l10n
+        context.use_l10n = self.use_l10n
+        output = self.nodelist.render(context)
+        context.use_l10n = old_setting
+        return output
+
+@register.tag('localize')
+def localize_tag(parser, token):
+    """
+    Forces or prevents localization of values, regardless of the value of
+    `settings.USE_L10N`.
+
+    Sample usage::
+
+        {% localize off %}
+            var pi = {{ 3.1415 }};
+        {% endlocalize %}
+
+    """
+    use_l10n = None
+    bits = list(token.split_contents())
+    if len(bits) == 1:
+        use_l10n = True
+    elif len(bits) > 2 or bits[1] not in ('on', 'off'):
+        raise TemplateSyntaxError("%r argument should be 'on' or 'off'" % bits[0])
+    else:
+        use_l10n = bits[1] == 'on'
+    nodelist = parser.parse(('endlocalize',))
+    parser.delete_first_token()
+    return LocalizeNode(nodelist, use_l10n)
+
+register.filter(localize)
+register.filter(unlocalize)
diff --git a/django/utils/formats.py b/django/utils/formats.py
index e64cc4e95a..18fcbb600f 100644
--- a/django/utils/formats.py
+++ b/django/utils/formats.py
@@ -41,14 +41,17 @@ def get_format_modules(reverse=False):
         modules.reverse()
     return modules
 
-def get_format(format_type, lang=None):
+def get_format(format_type, lang=None, use_l10n=None):
     """
     For a specific format type, returns the format for the current
     language (locale), defaults to the format in the settings.
     format_type is the name of the format, e.g. 'DATE_FORMAT'
+
+    If use_l10n is provided and is not None, that will force the value to
+    be localized (or not), overriding the value of settings.USE_L10N.
     """
     format_type = smart_str(format_type)
-    if settings.USE_L10N:
+    if use_l10n or (use_l10n is None and settings.USE_L10N):
         if lang is None:
             lang = get_language()
         cache_key = (format_type, lang)
@@ -65,48 +68,60 @@ def get_format(format_type, lang=None):
             _format_cache[cache_key] = None
     return getattr(settings, format_type)
 
-def date_format(value, format=None):
+def date_format(value, format=None, use_l10n=None):
     """
     Formats a datetime.date or datetime.datetime object using a
     localizable format
-    """
-    return dateformat.format(value, get_format(format or 'DATE_FORMAT'))
 
-def time_format(value, format=None):
+    If use_l10n is provided and is not None, that will force the value to
+    be localized (or not), overriding the value of settings.USE_L10N.
+    """
+    return dateformat.format(value, get_format(format or 'DATE_FORMAT', use_l10n=use_l10n))
+
+def time_format(value, format=None, use_l10n=None):
     """
     Formats a datetime.time object using a localizable format
-    """
-    return dateformat.time_format(value, get_format(format or 'TIME_FORMAT'))
 
-def number_format(value, decimal_pos=None):
+    If use_l10n is provided and is not None, that will force the value to
+    be localized (or not), overriding the value of settings.USE_L10N.
+    """
+    return dateformat.time_format(value, get_format(format or 'TIME_FORMAT', use_l10n=use_l10n))
+
+def number_format(value, decimal_pos=None, use_l10n=None):
     """
     Formats a numeric value using localization settings
+
+    If use_l10n is provided and is not None, that will force the value to
+    be localized (or not), overriding the value of settings.USE_L10N.
     """
-    if settings.USE_L10N:
+    if use_l10n or (use_l10n is None and settings.USE_L10N):
         lang = get_language()
     else:
         lang = None
     return numberformat.format(
         value,
-        get_format('DECIMAL_SEPARATOR', lang),
+        get_format('DECIMAL_SEPARATOR', lang, use_l10n=use_l10n),
         decimal_pos,
-        get_format('NUMBER_GROUPING', lang),
-        get_format('THOUSAND_SEPARATOR', lang),
+        get_format('NUMBER_GROUPING', lang, use_l10n=use_l10n),
+        get_format('THOUSAND_SEPARATOR', lang, use_l10n=use_l10n),
     )
 
-def localize(value):
+def localize(value, use_l10n=None):
     """
     Checks if value is a localizable type (date, number...) and returns it
-    formatted as a string using current locale format
+    formatted as a string using current locale format.
+
+    If use_l10n is provided and is not None, that will force the value to
+    be localized (or not), overriding the value of settings.USE_L10N.
     """
     if isinstance(value, (decimal.Decimal, float, int, long)):
-        return number_format(value)
+        return number_format(value, use_l10n=use_l10n)
     elif isinstance(value, datetime.datetime):
-        return date_format(value, 'DATETIME_FORMAT')
+        return date_format(value, 'DATETIME_FORMAT', use_l10n=use_l10n)
     elif isinstance(value, datetime.date):
-        return date_format(value)
+        return date_format(value, use_l10n=use_l10n)
     elif isinstance(value, datetime.time):
-        return time_format(value, 'TIME_FORMAT')
+        return time_format(value, 'TIME_FORMAT', use_l10n=use_l10n)
     else:
         return value
 
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
index 8e166d802f..7bb4481904 100644
--- a/docs/ref/templates/builtins.txt
+++ b/docs/ref/templates/builtins.txt
@@ -2113,3 +2113,12 @@ Django templates. It is slightly different from the libraries described
 above because you don't need to add any application to the ``INSTALLED_APPS``
 setting but rather set :setting:`USE_I18N` to True, then loading it with
 ``{% load i18n %}``. See :ref:`specifying-translation-strings-in-template-code`.
+
+l10n
+~~~~
+
+Provides a couple of templatetags that allow control over the localization of
+values in Django templates. It is slightly different from the libraries described
+above because you don't need to add any application to the ``INSTALLED_APPS``;
+you only need to load the library using ``{% load l10n %}``. See
+:ref:`topic-l10n-templates`.
diff --git a/docs/topics/i18n/localization.txt b/docs/topics/i18n/localization.txt
index 38d74e68e3..df89851039 100644
--- a/docs/topics/i18n/localization.txt
+++ b/docs/topics/i18n/localization.txt
@@ -2,11 +2,13 @@
 Localization
 ============
 
-This document covers two localization-related topics: `Creating language
-files`_ and `locale aware date, time and numbers input/output in forms`_
+This document covers three localization-related topics: `Creating language
+files`_ , `locale aware date, time and numbers input/output in forms`_,
+and `controlling localization in templates`_.
 
 .. _`Creating language files`: how-to-create-language-files_
 .. _`locale aware date, time and numbers input/output in forms`: format-localization_
+.. _`controlling localization in templates`: topic-l10n-templates
 
 .. seealso::
 
@@ -315,3 +317,94 @@ where :file:`formats.py` contains custom format definitions. For example::
 
 to use a space as a thousand separator, instead of the default for English,
 a comma.
+
+.. topic-l10n-templates:
+
+Controlling localization in templates
+=====================================
+
+When you have enabled localization using :setting:`USE_L10N`, Django
+will try to use a locale specific format whenever it outputs a value
+in a template.
+
+However, it may not always be appropriate to use localized values --
+for example, if you're outputting Javascript or XML that is designed
+to be machine-readable, you will always want unlocalized values. You
+may also want to use localization in selected templates, rather than
+using localization everywhere.
+
+To allow for fine control over the use of localization, Django
+provides a the ``l10n`` template library that contains the following
+tags and filters.
+
+Template tags
+-------------
+
+.. templatetag:: localize
+
+localize
+~~~~~~~~
+
+.. versionadded:: 1.3
+
+Enables or disables localization of template variables in the
+contained block.
+
+This tag allows a more fine grained control of localization than
+:setting:`USE_L10N`.
+
+To activate or deactivate localization for a template block, use::
+
+    {% localize on %}
+        {{ value }}
+    {% endlocalize %}
+
+    {% localize off %}
+        {{ value }}
+    {% endlocalize %}
+
+.. note::
+
+    The value of :setting:`USE_L10N` is not respected inside of a
+    `{% localize %}` block.
+
+See :tfilter:`localized` and :tfilter:`unlocalized` for a template filter that will
+do the same job on a per-variable basis.
+
+Template filters
+----------------
+
+.. templatefilter:: localize
+
+localize
+~~~~~~~~
+
+.. versionadded:: 1.3
+
+Forces localization of a single value.
+
+For example::
+
+    {{ value|localize }}
+
+To disable localization on a single value, use :tfilter:`unlocalize`. To control
+localization over a large section of a template, use the :ttag:`localize` template
+tag.
+
+
+.. templatefilter:: unlocalize
+
+unlocalize
+~~~~~~~~~~
+
+.. versionadded:: 1.3
+
+Forces a single value to be printed without localization.
+
+For example::
+
+    {{ value|unlocalize }}
+
+To force localization of a single value, use :tfilter:`localize`. To
+control localization over a large section of a template, use the
+:ttag:`localize` template tag.
diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
index 4aa52b6b55..bac77b0dbc 100644
--- a/tests/regressiontests/i18n/tests.py
+++ b/tests/regressiontests/i18n/tests.py
@@ -453,6 +453,33 @@ class FormattingTests(TestCase):
             settings.FORMAT_MODULE_PATH = old_format_module_path
             deactivate()
 
+    def test_localize_templatetag_and_filter(self):
+        """
+        Tests the {% localize %} templatetag
+        """
+        context = Context({'value': 3.14 })
+        template1 = Template("{% load l10n %}{% localize %}{{ value }}{% endlocalize %};{% localize on %}{{ value }}{% endlocalize %}")
+        template2 = Template("{% load l10n %}{{ value }};{% localize off %}{{ value }};{% endlocalize %}{{ value }}")
+        template3 = Template('{% load l10n %}{{ value }};{{ value|unlocalize }}')
+        template4 = Template('{% load l10n %}{{ value }};{{ value|localize }}')
+        output1 = '3,14;3,14'
+        output2 = '3,14;3.14;3,14'
+        output3 = '3,14;3.14'
+        output4 = '3.14;3,14'
+        old_localize = settings.USE_L10N
+        try:
+            activate('de')
+            settings.USE_L10N = False
+            self.assertEqual(template1.render(context), output1)
+            self.assertEqual(template4.render(context), output4)
+            settings.USE_L10N = True
+            self.assertEqual(template1.render(context), output1)
+            self.assertEqual(template2.render(context), output2)
+            self.assertEqual(template3.render(context), output3)
+        finally:
+            deactivate()
+            settings.USE_L10N = old_localize
+
 class MiscTests(TestCase):
 
     def test_parse_spec_http_header(self):