Просмотр исходного кода

Makemessages support for handlebars

Rafał Pitoń 10 лет назад
Родитель
Сommit
b6195dd8d3

+ 13 - 6
misago/core/management/commands/makemessages.py

@@ -68,18 +68,25 @@ class HandlebarsTemplate(object):
 
             expression_bits = [b for b in smart_split(trimmed_expression)]
             function = expression_bits[0]
-            args = expression_bits[1:HELPERS[function] + 1]
-            return '%s(%s);' % (function, ', '.join(args))
+
+            args_count = HELPERS[function] + 1
+            if len(expression_bits) >= args_count:
+                args = expression_bits[1:HELPERS[function] + 1]
+                return '%s(%s);' % (function, ', '.join(args))
+            else:
+                return ''
+
         return HBS_EXPRESSION.sub(replace_expression, content)
 
 
-class HandlebasFile(object):
-    def __init__(self, hbs_path):
+class HandlebarsFile(object):
+    def __init__(self, hbs_path, make_js_file=True):
         self.hbs_path = hbs_path
         self.path_suffix = self.make_js_path_suffix(hbs_path)
         self.js_path = self.make_js_path(hbs_path, self.path_suffix)
 
-        self.make_js_file(self.hbs_path, self.js_path)
+        if make_js_file:
+            self.make_js_file(self.hbs_path, self.js_path)
 
     def make_js_path_suffix(self, hbs_path):
         return '%s.tmp.js' % md5(hbs_path).hexdigest()[:8]
@@ -133,7 +140,7 @@ class Command(BaseCommand):
     def prepare_tmp_js_files(self):
         files = []
         for hbs_file in Path(os.getcwd()).walkfiles('*.hbs'):
-            files.append(HandlebasFile(hbs_file))
+            files.append(HandlebarsFile(hbs_file))
         return files
 
     def cleanup_po_files(self, locales, tmp_js_files):

+ 177 - 0
misago/core/tests/test_makemessages.py

@@ -0,0 +1,177 @@
+from django.test import TestCase
+
+from misago.core.management.commands.makemessages import (HandlebarsTemplate,
+                                                          HandlebarsFile)
+
+
+class HandlebarsFileTests(TestCase):
+    def test_make_js_path(self):
+        """Object correctly translates hbs path to temp js path"""
+        hbs_path = "templates/application.hbs"
+        test_file = HandlebarsFile(hbs_path, False)
+
+        suffix = test_file.make_js_path_suffix(hbs_path)
+        self.assertTrue(suffix.endswith(".tmp.js"))
+
+        js_path = test_file.make_js_path(hbs_path, suffix)
+        self.assertTrue(js_path.startswith(hbs_path))
+        self.assertTrue(js_path.endswith(suffix))
+
+
+class HandlebarsTemplateTests(TestCase):
+    def test_empty_file(self):
+        """empty file causes no errors"""
+        template = HandlebarsTemplate("")
+        self.assertEqual(template.get_converted_content(), "")
+
+    def test_stripped_expression(self):
+        """non-i18n expression is stripped"""
+        template = HandlebarsTemplate("{{ some.expression }}")
+        self.assertEqual(template.get_converted_content(), "")
+
+    def test_invalid_expression_stripping(self):
+        """invalid i18n expressions are stripped"""
+        template = HandlebarsTemplate("{{gettext }}")
+        self.assertEqual(template.get_converted_content(), "")
+
+        template = HandlebarsTemplate("{{ngettext }}")
+        self.assertEqual(template.get_converted_content(), "")
+
+        template = HandlebarsTemplate("{{ngettext 'apple' }}")
+        self.assertEqual(template.get_converted_content(), "")
+
+        template = HandlebarsTemplate("{{ngettext 'apple' 'apples' }}")
+        self.assertEqual(template.get_converted_content(), "")
+
+        template = HandlebarsTemplate("{{gettext_noop }}")
+        self.assertEqual(template.get_converted_content(), "")
+
+        template = HandlebarsTemplate("{{pgettext }}")
+        self.assertEqual(template.get_converted_content(), "")
+
+        template = HandlebarsTemplate("{{pgettext 'apple' }}")
+        self.assertEqual(template.get_converted_content(), "")
+
+        template = HandlebarsTemplate("{{npgettext 'fruit' 'apple' }}")
+        self.assertEqual(template.get_converted_content(), "")
+
+    def test_valid_expression_replace(self):
+        """valid i18n expressions are replaced"""
+        template = HandlebarsTemplate("{{gettext 'Lorem ipsum'}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext('Lorem ipsum');")
+
+        template = HandlebarsTemplate("{{gettext 'Lorem %(vis)s' vis=name}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext('Lorem %(vis)s');")
+
+        template = HandlebarsTemplate("{{gettext some_variable}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext(some_variable);")
+
+        template = HandlebarsTemplate("{{gettext 'Lorem ipsum'}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext('Lorem ipsum');")
+
+        template = HandlebarsTemplate("{{gettext 'Lorem %(vis)s' vis=name}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext('Lorem %(vis)s');")
+
+        template = HandlebarsTemplate("{{gettext some_variable}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext(some_variable);")
+
+        template = HandlebarsTemplate("{{gettext some_variable user=user.username}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext(some_variable);")
+
+        template = HandlebarsTemplate("{{ngettext '%(count)s apple' '%(count)s apples' apples_count}}")
+        self.assertEqual(template.get_converted_content(),
+                         "ngettext('%(count)s apple', '%(count)s apples', apples_count);")
+
+        template = HandlebarsTemplate("{{ngettext '%(user)s has %(count)s apple' '%(user)s has %(count)s apples' apples_count user=user.username}}")
+        self.assertEqual(template.get_converted_content(),
+                         "ngettext('%(user)s has %(count)s apple', '%(user)s has %(count)s apples', apples_count);")
+
+        template = HandlebarsTemplate("{{ngettext apple apples apples_count}}")
+        self.assertEqual(template.get_converted_content(),
+                         "ngettext(apple, apples, apples_count);")
+
+        template = HandlebarsTemplate("{{ngettext '%(count)s apple' apples apples_count}}")
+        self.assertEqual(template.get_converted_content(),
+                         "ngettext('%(count)s apple', apples, apples_count);")
+
+        template = HandlebarsTemplate("{{ngettext '%(user)s has %(count)s apple' apples apples_count user=user.username}}")
+        self.assertEqual(template.get_converted_content(),
+                         "ngettext('%(user)s has %(count)s apple', apples, apples_count);")
+
+        template = HandlebarsTemplate("{{gettext_noop 'Lorem ipsum'}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext_noop('Lorem ipsum');")
+
+        template = HandlebarsTemplate("{{gettext_noop 'Lorem %(vis)s' vis=name}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext_noop('Lorem %(vis)s');")
+
+        template = HandlebarsTemplate("{{gettext_noop some_variable}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext_noop(some_variable);")
+
+        template = HandlebarsTemplate("{{gettext_noop 'Lorem ipsum'}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext_noop('Lorem ipsum');")
+
+        template = HandlebarsTemplate("{{gettext_noop 'Lorem %(vis)s' vis=name}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext_noop('Lorem %(vis)s');")
+
+        template = HandlebarsTemplate("{{gettext_noop some_variable}}")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext_noop(some_variable);")
+
+        template = HandlebarsTemplate("{{pgettext 'month' 'may'}}")
+        self.assertEqual(template.get_converted_content(),
+                         "pgettext('month', 'may');")
+
+        template = HandlebarsTemplate("{{pgettext 'month' month_name}}")
+        self.assertEqual(template.get_converted_content(),
+                         "pgettext('month', month_name);")
+
+        template = HandlebarsTemplate("{{pgettext 'day of month' 'May, %(day)s' day=calendar.day}}")
+        self.assertEqual(template.get_converted_content(),
+                         "pgettext('day of month', 'May, %(day)s');")
+
+        template = HandlebarsTemplate("{{pgettext context value day=calendar.day}}")
+        self.assertEqual(template.get_converted_content(),
+                         "pgettext(context, value);")
+
+        template = HandlebarsTemplate("{{npgettext 'fruits' '%(count)s apple' '%(count)s apples' apples_count}}")
+        self.assertEqual(template.get_converted_content(),
+                         "npgettext('fruits', '%(count)s apple', '%(count)s apples', apples_count);")
+
+        template = HandlebarsTemplate("{{npgettext 'fruits' '%(user)s has %(count)s apple' '%(user)s has %(count)s apples' apples_count user=user.username}}")
+        self.assertEqual(template.get_converted_content(),
+                         "npgettext('fruits', '%(user)s has %(count)s apple', '%(user)s has %(count)s apples', apples_count);")
+
+        template = HandlebarsTemplate("{{npgettext context apple apples apples_count}}")
+        self.assertEqual(template.get_converted_content(),
+                         "npgettext(context, apple, apples, apples_count);")
+
+        template = HandlebarsTemplate("{{npgettext context '%(count)s apple' apples apples_count}}")
+        self.assertEqual(template.get_converted_content(),
+                         "npgettext(context, '%(count)s apple', apples, apples_count);")
+
+        template = HandlebarsTemplate("{{npgettext 'fruits' '%(user)s has %(count)s apple' apples apples_count user=user.username}}")
+        self.assertEqual(template.get_converted_content(),
+                         "npgettext('fruits', '%(user)s has %(count)s apple', apples, apples_count);")
+
+    def test_multiple_expressions(self):
+        """multiple expressions are handled"""
+        template = HandlebarsTemplate("{{gettext 'Posted by:'}} <strong>{{gettext user.rank.title}}</strong>; <em>{{ user.city }}</em>")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext('Posted by:');gettext(user.rank.title);")
+
+        template = HandlebarsTemplate("""{{gettext 'Posted by:'}}<br>
+                                         {{gettext user.rank.title}}""")
+        self.assertEqual(template.get_converted_content(),
+                         "gettext('Posted by:');\ngettext(user.rank.title);")

+ 1 - 0
misago/static/misago/app/django-i18n.js

@@ -18,6 +18,7 @@ Ember.Handlebars.registerBoundHelper('gettext', function(msgid, options) {
 });
 
 Ember.Handlebars.registerBoundHelper('ngettext', function(singular, plural, count, options) {
+  options.hash['count'] = count
   return interpolate(ngettext(singular, plural, count), options.hash, true);
 });