mirror of
https://github.com/django/django.git
synced 2025-07-05 02:09:13 +00:00
i18n: changed resolve_variable and resolve_variable_with_filters to allways
accept string constants and to accept i18n string constants with _(), too. That way the i18n tag isn't needed in simple cases. git-svn-id: http://code.djangoproject.com/svn/django/branches/i18n@760 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
280747f757
commit
ae3c26df62
@ -254,11 +254,15 @@ class FilterParser:
|
||||
self.filters = []
|
||||
self.current_filter_name = None
|
||||
self.current_filter_arg = None
|
||||
# First read the variable part
|
||||
self.var = self.read_alphanumeric_token()
|
||||
# First read the variable part - decide on wether we need
|
||||
# to parse a string or a variable by peeking into the stream
|
||||
if self.peek_char() in ('_', '"', "'"):
|
||||
self.var = self.read_constant_string_token()
|
||||
else:
|
||||
self.var = self.read_alphanumeric_token()
|
||||
if not self.var:
|
||||
raise TemplateSyntaxError, "Could not read variable name: '%s'" % self.s
|
||||
if self.var.find(VARIABLE_ATTRIBUTE_SEPARATOR + '_') > -1 or self.var[0] == '_':
|
||||
if self.var.find(VARIABLE_ATTRIBUTE_SEPARATOR + '_') > -1 or (self.var[0] == '_' and not self.var.startswith('_(')):
|
||||
raise TemplateSyntaxError, "Variables and attributes may not begin with underscores: '%s'" % self.var
|
||||
# Have we reached the end?
|
||||
if self.current is None:
|
||||
@ -268,6 +272,12 @@ class FilterParser:
|
||||
# We have a filter separator; start reading the filters
|
||||
self.read_filters()
|
||||
|
||||
def peek_char(self):
|
||||
try:
|
||||
return self.s[self.i+1]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def next_char(self):
|
||||
self.i = self.i + 1
|
||||
try:
|
||||
@ -275,6 +285,39 @@ class FilterParser:
|
||||
except IndexError:
|
||||
self.current = None
|
||||
|
||||
def read_constant_string_token(self):
|
||||
"""Read a constant string that must be delimited by either "
|
||||
or ' characters. The string is returned with it's delimiters
|
||||
and a possible i18n tag."""
|
||||
val = ''
|
||||
i18n = False
|
||||
qchar = None
|
||||
self.next_char()
|
||||
if self.current == '_':
|
||||
self.next_char()
|
||||
if self.current != '(':
|
||||
raise TemplateSyntaxError, "Bad character (expecting '(') '%s'" % self.current
|
||||
i18n = True
|
||||
val = '_('
|
||||
self.next_char()
|
||||
if not self.current in ('"', "'"):
|
||||
raise TemplateSyntaxError, "Bad character (expecting '\"' or ''') '%s'" % self.current
|
||||
qchar = self.current
|
||||
val += qchar
|
||||
while 1:
|
||||
self.next_char()
|
||||
if self.current == qchar:
|
||||
break
|
||||
val += self.current
|
||||
val += self.current
|
||||
if i18n:
|
||||
self.next_char()
|
||||
if self.current != ')':
|
||||
raise TemplateSyntaxError, "Bad character (expecting ')') '%s'" % self.current
|
||||
val += self.current
|
||||
self.next_char()
|
||||
return val
|
||||
|
||||
def read_alphanumeric_token(self):
|
||||
"""Read a variable name or filter name, which are continuous strings of
|
||||
alphanumeric characters + the underscore"""
|
||||
@ -372,8 +415,10 @@ def resolve_variable(path, context):
|
||||
|
||||
(The example assumes VARIABLE_ATTRIBUTE_SEPARATOR is '.')
|
||||
"""
|
||||
if path[0] in ('"', "'") and path[0] == path[-1]:
|
||||
if path[0] in ('"', "'") and path[0] == path[-1]:
|
||||
current = path[1:-1]
|
||||
elif path.startswith('_(') and path.endswith(')') and path[2] in ("'", '"') and path[-2] == path[2]:
|
||||
current = _(path[3:-2])
|
||||
else:
|
||||
current = context
|
||||
bits = path.split(VARIABLE_ATTRIBUTE_SEPARATOR)
|
||||
|
@ -102,6 +102,20 @@ variables, not more complex expressions.
|
||||
To translate a variable value, you can just do {% i18n _(variable) %}. This
|
||||
can even include filters like {% i18n _(variable|lower} %}.
|
||||
|
||||
There is additional support for i18n string constants for other situations
|
||||
as well. All template tags that do variable resolving (with or without filters)
|
||||
will accept string constants, too. Those string constants can now be i18n
|
||||
strings like this::
|
||||
|
||||
<html>
|
||||
<title>{{ _('This is the title') }}</title>
|
||||
<body>
|
||||
<p>{{ _('Hello World!') }}</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
This is much shorter, but won't allow you to use gettext_noop or ngettext.
|
||||
|
||||
How the Language is Discovered
|
||||
==============================
|
||||
|
||||
|
@ -241,6 +241,9 @@ TEMPLATE_TESTS = {
|
||||
|
||||
# simple non-translation (only marking) of a string to german
|
||||
'i18n10': ('{% i18n gettext_noop("Page not found") %}', {'LANGUAGE_CODE': 'de'}, "Page not found"),
|
||||
|
||||
# translation of string without i18n tag
|
||||
'i18n11': ('{{ _("blah") }}', {}, "blah"),
|
||||
}
|
||||
|
||||
# This replaces the standard template_loader.
|
||||
|
Loading…
x
Reference in New Issue
Block a user