Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Finished support for newstyle gettext translations

--HG--
branch : trunk
  • Loading branch information...
commit b8892e7b036118015b158b173f73845878166d03 1 parent 4da9034
@mitsuhiko authored
Showing with 71 additions and 21 deletions.
  1. +7 −0 jinja2/environment.py
  2. +9 −13 jinja2/ext.py
  3. +55 −8 jinja2/testsuite/ext.py
View
7 jinja2/environment.py
@@ -279,6 +279,13 @@ def __init__(self,
_environment_sanity_check(self)
+ def add_extension(self, extension):
+ """Adds an extension after the environment was created.
+
+ .. versionadded:: 2.5
+ """
+ load_extensions(self, [extension])
+
def extend(self, **attributes):
"""Add the items to the instance of the environment if they do not exist
yet. This is used by :ref:`extensions <writing-extensions>` to register
View
22 jinja2/ext.py
@@ -124,13 +124,13 @@ def call_method(self, name, args=None, kwargs=None, dyn_args=None,
@contextfunction
def _gettext_alias(__context, *args, **kwargs):
- return __context.resolve('gettext')(*args, **kwargs)
+ return __context.call(__context.resolve('gettext'), *args, **kwargs)
def _make_new_gettext(func):
@contextfunction
def gettext(__context, __string, **variables):
- rv = func(__string)
+ rv = __context.call(func, __string)
if __context.eval_ctx.autoescape:
rv = Markup(rv)
return rv % variables
@@ -141,7 +141,7 @@ def _make_new_ngettext(func):
@contextfunction
def ngettext(__context, __singular, __plural, num, **variables):
variables.setdefault('num', num)
- rv = func(__singular, __plural, num)
+ rv = __context.call(func, __singular, __plural, num)
if __context.eval_ctx.autoescape:
rv = Markup(rv)
return rv % variables
@@ -286,12 +286,6 @@ def parse(self, parser):
elif plural_expr is None:
parser.fail('pluralize without variables', lineno)
- if variables:
- variables = nodes.Dict([nodes.Pair(nodes.Const(x, lineno=lineno), y)
- for x, y in variables.items()])
- else:
- variables = None
-
node = self._make_node(singular, plural, variables, plural_expr)
node.set_lineno(lineno)
return node
@@ -349,9 +343,8 @@ def _make_node(self, singular, plural, variables, plural_expr):
# enough to handle the variable expansion and autoescape
# handling itself
if self.environment.newstyle_gettext:
- if variables is None:
- variables = nodes.Dict([])
- node.kwargs = variables
+ for key, value in variables.iteritems():
+ node.kwargs.append(nodes.Keyword(key, value))
# otherwise do that here
else:
@@ -359,7 +352,10 @@ def _make_node(self, singular, plural, variables, plural_expr):
# environment with autoescaping turned on
node = nodes.MarkSafeIfAutoescape(node)
if variables:
- node = nodes.Mod(node, variables)
+ node = nodes.Mod(node, nodes.Dict([
+ nodes.Pair(nodes.Const(key), value)
+ for key, value in variables.items()
+ ]))
return nodes.Output([node])
View
63 jinja2/testsuite/ext.py
@@ -31,24 +31,37 @@
_gettext_re = re.compile(r'_\((.*?)\)(?s)')
-templates = {
+i18n_templates = {
'master.html': '<title>{{ page_title|default(_("missing")) }}</title>'
'{% block body %}{% endblock %}',
'child.html': '{% extends "master.html" %}{% block body %}'
'{% trans %}watch out{% endtrans %}{% endblock %}',
'plural.html': '{% trans user_count %}One user online{% pluralize %}'
'{{ user_count }} users online{% endtrans %}',
- 'stringformat.html': '{{ _("User: %d")|format(user_count) }}'
+ 'stringformat.html': '{{ _("User: %(num)d")|format(num=user_count) }}'
+}
+
+newstyle_i18n_templates = {
+ 'master.html': '<title>{{ page_title|default(_("missing")) }}</title>'
+ '{% block body %}{% endblock %}',
+ 'child.html': '{% extends "master.html" %}{% block body %}'
+ '{% trans %}watch out{% endtrans %}{% endblock %}',
+ 'plural.html': '{% trans user_count %}One user online{% pluralize %}'
+ '{{ user_count }} users online{% endtrans %}',
+ 'stringformat.html': '{{ _("User: %(num)d", num=user_count) }}',
+ 'ngettext.html': '{{ ngettext("%(num)d apple", "%(num)d apples", apples) }}'
}
languages = {
'de': {
- 'missing': 'fehlend',
- 'watch out': 'pass auf',
- 'One user online': 'Ein Benutzer online',
- '%(user_count)s users online': '%(user_count)s Benutzer online',
- 'User: %d': 'Benutzer: %d'
+ 'missing': u'fehlend',
+ 'watch out': u'pass auf',
+ 'One user online': u'Ein Benutzer online',
+ '%(user_count)s users online': u'%(user_count)s Benutzer online',
+ 'User: %(num)d': u'Benutzer: %(num)d',
+ '%(num)d apple': u'%(num)d Apfel',
+ '%(num)d apples': u'%(num)d Äpfel'
}
}
@@ -68,7 +81,7 @@ def ngettext(context, s, p, n):
i18n_env = Environment(
- loader=DictLoader(templates),
+ loader=DictLoader(i18n_templates),
extensions=['jinja2.ext.i18n']
)
i18n_env.globals.update({
@@ -77,6 +90,11 @@ def ngettext(context, s, p, n):
'ngettext': ngettext
})
+newstyle_i18n_env = Environment(
+ loader=DictLoader(newstyle_i18n_templates),
+ extensions=['jinja2.ext.i18n']
+)
+newstyle_i18n_env.install_gettext_callables(gettext, ngettext, newstyle=True)
class TestExtension(Extension):
tags = set(['test'])
@@ -266,6 +284,34 @@ def test_comment_extract(self):
]
+class NewstyleInternationalizationTestCase(JinjaTestCase):
+
+ def test_trans(self):
+ tmpl = newstyle_i18n_env.get_template('child.html')
+ assert tmpl.render(LANGUAGE='de') == '<title>fehlend</title>pass auf'
+
+ def test_trans_plural(self):
+ tmpl = newstyle_i18n_env.get_template('plural.html')
+ assert tmpl.render(LANGUAGE='de', user_count=1) == 'Ein Benutzer online'
+ assert tmpl.render(LANGUAGE='de', user_count=2) == '2 Benutzer online'
+
+ def test_complex_plural(self):
+ tmpl = newstyle_i18n_env.from_string('{% trans foo=42, count=2 %}{{ count }} item{% '
+ 'pluralize count %}{{ count }} items{% endtrans %}')
+ assert tmpl.render() == '2 items'
+ self.assert_raises(TemplateAssertionError, i18n_env.from_string,
+ '{% trans foo %}...{% pluralize bar %}...{% endtrans %}')
+
+ def test_trans_stringformatting(self):
+ tmpl = newstyle_i18n_env.get_template('stringformat.html')
+ assert tmpl.render(LANGUAGE='de', user_count=5) == 'Benutzer: 5'
+
+ def test_newstyle_plural(self):
+ tmpl = newstyle_i18n_env.get_template('ngettext.html')
+ assert tmpl.render(LANGUAGE='de', apples=1) == '1 Apfel'
+ assert tmpl.render(LANGUAGE='de', apples=5) == u'5 Äpfel'
+
+
class AutoEscapeTestCase(JinjaTestCase):
def test_scoped_setting(self):
@@ -347,5 +393,6 @@ def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(ExtensionsTestCase))
suite.addTest(unittest.makeSuite(InternationalizationTestCase))
+ suite.addTest(unittest.makeSuite(NewstyleInternationalizationTestCase))
suite.addTest(unittest.makeSuite(AutoEscapeTestCase))
return suite
Please sign in to comment.
Something went wrong with that request. Please try again.