mirror of
https://github.com/django/django.git
synced 2025-04-21 07:44:36 +00:00
i18n: updated unittests and fixed bugs in the tags, removed the old tags and fixed #719 (thx nesh)
git-svn-id: http://code.djangoproject.com/svn/django/branches/i18n@1064 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
ed05d90232
commit
1470bb0b23
@ -290,63 +290,6 @@ class WidthRatioNode(Node):
|
||||
return ''
|
||||
return str(int(round(ratio)))
|
||||
|
||||
class GetAvailableLanguagesNode(Node):
|
||||
|
||||
def __init__(self, variable):
|
||||
self.variable = variable
|
||||
|
||||
def render(self, context):
|
||||
from django.conf.settings import LANGUAGES
|
||||
context[self.variable] = LANGUAGES
|
||||
return ''
|
||||
|
||||
class I18NNode(Node):
|
||||
|
||||
def __init__(self, cmd):
|
||||
self.cmd = cmd
|
||||
self.i18n_re = re.compile(r'^\s*(_|gettext|gettext_noop)\((.*)\)\s*$')
|
||||
self.ngettext_re = re.compile(r'''^\s*ngettext\(((?:".+")|(?:'.+')|(?:""".+"""))\s*,\s*((?:".+")|(?:'.+')|(?:""".+"""))\s*,\s*(.*)\)\s*$''')
|
||||
|
||||
def _resolve_var(self, s, context):
|
||||
if s.startswith("'") and s.endswith("'"):
|
||||
s = s[1:-1]
|
||||
elif s.startswith('"""') and s.endswith('"""'):
|
||||
s = s[3:-3]
|
||||
elif s.startswith('"') and s.endswith('"'):
|
||||
s = s[1:-1]
|
||||
else:
|
||||
s = resolve_variable_with_filters(s, context)
|
||||
return s
|
||||
|
||||
def render(self, context):
|
||||
m = self.i18n_re.match(self.cmd)
|
||||
if m:
|
||||
f = m.group(1)
|
||||
s = self._resolve_var(m.group(2), context)
|
||||
if f in ('_', 'gettext'):
|
||||
return translation.gettext(s) % context
|
||||
elif f == 'gettext_noop':
|
||||
return translation.gettext_noop(s) % context
|
||||
else:
|
||||
raise TemplateSyntaxError("i18n only supports _, gettext, gettext_noop and ngettext as functions, not %s" % f)
|
||||
m = self.ngettext_re.match(self.cmd)
|
||||
if m:
|
||||
singular = self._resolve_var(m.group(1), context)
|
||||
plural = self._resolve_var(m.group(2), context)
|
||||
var = resolve_variable_with_filters(m.group(3), context)
|
||||
return translation.ngettext(singular, plural, var) % context
|
||||
raise TemplateSyntaxError("i18n must be called as {% i18n _('some message') %} or {% i18n ngettext('singular', 'plural', var) %}")
|
||||
|
||||
cyclevars = [v for v in args[1].split(",") if v] # split and kill blanks
|
||||
name = args[3]
|
||||
node = CycleNode(cyclevars)
|
||||
|
||||
if not hasattr(parser, '_namedCycleNodes'):
|
||||
parser._namedCycleNodes = {}
|
||||
|
||||
parser._namedCycleNodes[name] = node
|
||||
return node
|
||||
|
||||
def do_comment(parser, token):
|
||||
"""
|
||||
Ignore everything between ``{% comment %}`` and ``{% endcomment %}``
|
||||
@ -813,45 +756,6 @@ def do_widthratio(parser, token):
|
||||
raise TemplateSyntaxError("widthratio final argument must be an integer")
|
||||
return WidthRatioNode(this_value_var, max_value_var, max_width)
|
||||
|
||||
def do_get_available_languages(parser, token):
|
||||
"""
|
||||
This will store a list of available languages
|
||||
in the context.
|
||||
|
||||
Usage is as follows::
|
||||
|
||||
{% get_available_languages as languages %}
|
||||
{% for language in languages %}
|
||||
...
|
||||
{% endfor %}
|
||||
|
||||
This will just pull the LANGUAGES setting from
|
||||
your setting file (or the default settings) and
|
||||
put it into the named variable.
|
||||
"""
|
||||
|
||||
args = token.contents.split()
|
||||
if len(args) != 3 or args[1] != 'as':
|
||||
raise template.TemplateSyntaxError("'get_available_languages' requires 'as variable' (got %r)" % args)
|
||||
return GetAvailableLanguagesNode(args[2])
|
||||
|
||||
def do_i18n(parser, token):
|
||||
"""
|
||||
translate a given string with the current
|
||||
translation object.
|
||||
|
||||
For example::
|
||||
|
||||
{% i18n _('test') %}
|
||||
{% i18n ngettext('singular', 'plural', counter) %}
|
||||
|
||||
"""
|
||||
args = token.contents.split(' ', 1)
|
||||
if len(args) != 2:
|
||||
raise template.TemplateSyntaxError("'i18n' requires one argument (got %r)" % args)
|
||||
|
||||
return I18NNode(args[1].strip())
|
||||
|
||||
register_tag('comment', do_comment)
|
||||
register_tag('cycle', do_cycle)
|
||||
register_tag('debug', do_debug)
|
||||
@ -868,5 +772,3 @@ register_tag('load', do_load)
|
||||
register_tag('now', do_now)
|
||||
register_tag('templatetag', do_templatetag)
|
||||
register_tag('widthratio', do_widthratio)
|
||||
register_tag('i18n', do_i18n)
|
||||
register_tag('get_available_languages', do_get_available_languages)
|
||||
|
@ -18,7 +18,7 @@ class GetAvailableLanguagesNode(Node):
|
||||
context[self.variable] = LANGUAGES
|
||||
return ''
|
||||
|
||||
class GetCurrentLanguage(Node):
|
||||
class GetCurrentLanguageNode(Node):
|
||||
|
||||
def __init__(self, variable):
|
||||
self.variable = variable
|
||||
@ -112,7 +112,7 @@ def do_get_current_language(parser, token):
|
||||
args = token.contents.split()
|
||||
if len(args) != 3 or args[1] != 'as':
|
||||
raise TemplateSyntaxError, "'get_available_languages' requires 'as variable' (got %r)" % args
|
||||
return GetAvailableLanguagesNode(args[2])
|
||||
return GetCurrentLanguageNode(args[2])
|
||||
|
||||
def do_translate(parser, token):
|
||||
"""
|
||||
@ -144,14 +144,21 @@ def do_translate(parser, token):
|
||||
the variable ``variable``. Make sure that the string
|
||||
in there is something that is in the .po file.
|
||||
"""
|
||||
args = token.contents.split(None, 1)
|
||||
p = args[1].rfind(' ')
|
||||
noop = False
|
||||
value = ''
|
||||
if p >= 0 and args[1][p:].strip() == 'noop':
|
||||
value = args[1][:p].strip()
|
||||
else:
|
||||
value = args[1]
|
||||
|
||||
class TranslateParser(TokenParser):
|
||||
|
||||
def top(self):
|
||||
value = self.value()
|
||||
if self.more():
|
||||
if self.tag() == 'noop':
|
||||
noop = True
|
||||
else:
|
||||
raise TemplateSyntaxError, "only option for 'trans' is 'noop'"
|
||||
else:
|
||||
noop = False
|
||||
return (value, noop)
|
||||
|
||||
(value, noop) = TranslateParser(token.contents).top()
|
||||
return TranslateNode(value, noop)
|
||||
|
||||
def do_block_translate(parser, token):
|
||||
@ -189,7 +196,7 @@ def do_block_translate(parser, token):
|
||||
singular.append(token)
|
||||
else:
|
||||
break
|
||||
if countervar and counter:
|
||||
if countervar and counter:
|
||||
if token.contents.strip() != 'plural':
|
||||
raise TemplateSyntaxError, "'blocktrans' doesn't allow other block tags inside it" % tag
|
||||
while parser.tokens:
|
||||
@ -200,11 +207,11 @@ def do_block_translate(parser, token):
|
||||
break
|
||||
if token.contents.strip() != 'endblocktrans':
|
||||
raise TemplateSyntaxError, "'blocktrans' doesn't allow other block tags (seen %r) inside it" % token.contents
|
||||
|
||||
|
||||
return BlockTranslateNode(extra_context, singular, plural, countervar, counter)
|
||||
|
||||
register_tag('get_available_languages', do_get_available_languages)
|
||||
register_tag('get_curent_language', do_get_current_language)
|
||||
register_tag('get_current_language', do_get_current_language)
|
||||
register_tag('trans', do_translate)
|
||||
register_tag('blocktrans', do_block_translate)
|
||||
|
||||
|
@ -218,49 +218,40 @@ TEMPLATE_TESTS = {
|
||||
'exception04': ("{% extends 'inheritance17' %}{% block first %}{% echo 400 %}5678{% endblock %}", {}, template.TemplateSyntaxError),
|
||||
|
||||
# simple translation of a string delimited by '
|
||||
'i18n01': ("{% i18n _('xxxyyyxxx') %}", {}, "xxxyyyxxx"),
|
||||
'i18n01': ("{% load i18n %}{% trans 'xxxyyyxxx' %}", {}, "xxxyyyxxx"),
|
||||
|
||||
# simple translation of a string delimited by "
|
||||
'i18n02': ('{% i18n _("xxxyyyxxx") %}', {}, "xxxyyyxxx"),
|
||||
|
||||
# simple translation of a string delimited by """
|
||||
'i18n03': ('{% i18n _("""xxxyyyxxx""") %}', {}, "xxxyyyxxx"),
|
||||
'i18n02': ('{% load i18n %}{% trans "xxxyyyxxx" %}', {}, "xxxyyyxxx"),
|
||||
|
||||
# simple translation of a variable
|
||||
'i18n04': ('{% i18n _(anton) %}', {'anton': 'xxxyyyxxx'}, "xxxyyyxxx"),
|
||||
'i18n03': ('{% load i18n %}{% blocktrans %}{{ anton }}{% endblocktrans %}', {'anton': 'xxxyyyxxx'}, "xxxyyyxxx"),
|
||||
|
||||
# simple translation of a variable
|
||||
'i18n05': ('{% i18n _(anton|lower) %}', {'anton': 'XXXYYYXXX'}, "xxxyyyxxx"),
|
||||
# simple translation of a variable and filter
|
||||
'i18n04': ('{% load i18n %}{% blocktrans with anton|lower as berta %}{{ berta }}{% endblocktrans %}', {'anton': 'XXXYYYXXX'}, "xxxyyyxxx"),
|
||||
|
||||
# simple translation of a string with interpolation
|
||||
'i18n05': ('{% i18n _("xxx%(anton)sxxx") %}', {'anton': 'yyy'}, "xxxyyyxxx"),
|
||||
'i18n05': ('{% load i18n %}{% blocktrans %}xxx{{ anton }}xxx{% endblocktrans %}', {'anton': 'yyy'}, "xxxyyyxxx"),
|
||||
|
||||
# simple translation of a string to german
|
||||
'i18n07': ('{% i18n _("Page not found") %}', {'LANGUAGE_CODE': 'de'}, "Seite nicht gefunden"),
|
||||
'i18n06': ('{% load i18n %}{% trans "Page not found" %}', {'LANGUAGE_CODE': 'de'}, "Seite nicht gefunden"),
|
||||
|
||||
# translation of singular form
|
||||
'i18n08': ('{% i18n ngettext("singular", "plural", count) %}', {'count': 1}, "singular"),
|
||||
'i18n07': ('{% load i18n %}{% blocktrans count number as counter %}singular{% plural %}plural{% endblocktrans %}', {'number': 1}, "singular"),
|
||||
|
||||
# translation of plural form
|
||||
'i18n09': ('{% i18n ngettext("singular", "plural", count) %}', {'count': 2}, "plural"),
|
||||
'i18n08': ('{% load i18n %}{% blocktrans count number as counter %}singular{% plural %}plural{% endblocktrans %}', {'number': 2}, "plural"),
|
||||
|
||||
# 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"),
|
||||
|
||||
# translation of string without i18n tag but with interpolation
|
||||
'i18n12': ('{{ _("blah%(anton)s") }}', {'anton': 'blubb'}, "blahblubb"),
|
||||
'i18n09': ('{% load i18n %}{% trans "Page not found" noop %}', {'LANGUAGE_CODE': 'de'}, "Page not found"),
|
||||
|
||||
# translation of a variable with a translated filter
|
||||
'i18n13': ('{{ bool|yesno:_("ja,nein") }}', {'bool': True}, 'ja'),
|
||||
'i18n10': ('{{ bool|yesno:_("ja,nein") }}', {'bool': True}, 'ja'),
|
||||
|
||||
# translation of a variable with a non-translated filter
|
||||
'i18n14': ('{{ bool|yesno:"ja,nein" }}', {'bool': True}, 'ja'),
|
||||
'i18n11': ('{{ bool|yesno:"ja,nein" }}', {'bool': True}, 'ja'),
|
||||
|
||||
# usage of the get_available_languages tag
|
||||
'i18n15': ('{% get_available_languages as langs %}{% for lang in langs %}{% ifequal lang.0 "de" %}{{ lang.0 }}{% endifequal %}{% endfor %}', {}, 'de'),
|
||||
'i18n12': ('{% load i18n %}{% get_available_languages as langs %}{% for lang in langs %}{% ifequal lang.0 "de" %}{{ lang.0 }}{% endifequal %}{% endfor %}', {}, 'de'),
|
||||
}
|
||||
|
||||
def test_template_loader(template_name, template_dirs=None):
|
||||
|
Loading…
x
Reference in New Issue
Block a user