summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorDoug Beck <doug@douglasbeck.com>2015-04-15 17:01:11 -0400
committerTim Graham <timograham@gmail.com>2015-08-12 10:23:34 -0400
commitb7508896fbe19ec2cdeb81565cd587091b6b68d0 (patch)
tree5efb501dcc753cdaf1314ba826ca59cd44c4297b /django
parentd772d812cf583e0f99e21850f26addf1d59bfa35 (diff)
Fixed #24257 -- Corrected i18n handling of percent signs.
Refactored tests to use a sample project. Updated extraction: * Removed special handling of single percent signs. * When extracting messages from template text, doubled all percent signs so they are not interpreted by gettext as string format flags. All strings extracted by gettext, if containing a percent sign, will now be labeled "#, python-format". Updated translation: * Used "%%" for "%" in template text before calling gettext. * Updated {% trans %} rendering to restore "%" from "%%".
Diffstat (limited to 'django')
-rw-r--r--django/template/base.py7
-rw-r--r--django/templatetags/i18n.py6
-rw-r--r--django/utils/translation/trans_real.py5
3 files changed, 13 insertions, 5 deletions
diff --git a/django/template/base.py b/django/template/base.py
index 71a97fda80..f15f8a6ff6 100644
--- a/django/template/base.py
+++ b/django/template/base.py
@@ -825,10 +825,13 @@ class Variable(object):
# We're dealing with a literal, so it's already been "resolved"
value = self.literal
if self.translate:
+ is_safe = isinstance(value, SafeData)
+ msgid = value.replace('%', '%%')
+ msgid = mark_safe(msgid) if is_safe else msgid
if self.message_context:
- return pgettext_lazy(self.message_context, value)
+ return pgettext_lazy(self.message_context, msgid)
else:
- return ugettext_lazy(value)
+ return ugettext_lazy(msgid)
return value
def __repr__(self):
diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py
index 4e77aaece4..050ef2c741 100644
--- a/django/templatetags/i18n.py
+++ b/django/templatetags/i18n.py
@@ -7,6 +7,7 @@ from django.template import Library, Node, TemplateSyntaxError, Variable
from django.template.base import TOKEN_TEXT, TOKEN_VAR, render_value_in_context
from django.template.defaulttags import token_kwargs
from django.utils import six, translation
+from django.utils.safestring import SafeData, mark_safe
register = Library()
@@ -86,6 +87,11 @@ class TranslateNode(Node):
self.message_context.resolve(context))
output = self.filter_expression.resolve(context)
value = render_value_in_context(output, context)
+ # Restore percent signs. Percent signs in template text are doubled
+ # so they are not interpreted as string format flags.
+ is_safe = isinstance(value, SafeData)
+ value = value.replace('%%', '%')
+ value = mark_safe(value) if is_safe else value
if self.asvar:
context[self.asvar] = value
return ''
diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py
index 8a2527022d..e05b5613a5 100644
--- a/django/utils/translation/trans_real.py
+++ b/django/utils/translation/trans_real.py
@@ -534,7 +534,6 @@ block_re = re.compile(r"""^\s*blocktrans(\s+.*context\s+((?:"[^"]*?")|(?:'[^']*?
endblock_re = re.compile(r"""^\s*endblocktrans$""")
plural_re = re.compile(r"""^\s*plural$""")
constant_re = re.compile(r"""_\(((?:".*?")|(?:'.*?'))\)""")
-one_percent_re = re.compile(r"""(?<!%)%(?!%)""")
def templatize(src, origin=None):
@@ -631,7 +630,7 @@ def templatize(src, origin=None):
else:
singular.append('%%(%s)s' % t.contents)
elif t.token_type == TOKEN_TEXT:
- contents = one_percent_re.sub('%%', t.contents)
+ contents = t.contents.replace('%', '%%')
if inplural:
plural.append(contents)
else:
@@ -667,7 +666,7 @@ def templatize(src, origin=None):
g = g.strip('"')
elif g[0] == "'":
g = g.strip("'")
- g = one_percent_re.sub('%%', g)
+ g = g.replace('%', '%%')
if imatch.group(2):
# A context is provided
context_match = context_re.match(imatch.group(2))