@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
@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
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
# 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:
# 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])
_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'
}
}
i18n_env = Environment(
- loader=DictLoader(templates),
+ loader=DictLoader(i18n_templates),
extensions=['jinja2.ext.i18n']
)
i18n_env.globals.update({
'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'])
]
+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):
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