1
0
mirror of https://github.com/django/django.git synced 2025-07-05 10:19:20 +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:
Georg Bauer 2005-10-01 16:24:21 +00:00
parent 280747f757
commit ae3c26df62
3 changed files with 66 additions and 4 deletions

View File

@ -254,11 +254,15 @@ class FilterParser:
self.filters = []
self.current_filter_name = None
self.current_filter_arg = None
# First read the variable part
# 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"""
@ -374,6 +417,8 @@ def resolve_variable(path, context):
"""
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)

View File

@ -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
==============================

View File

@ -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.