Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #13514 -- Corrected the process of loading multiple javascript …

…translation catalogs. Thanks to jtiai for the report, to Ramiro Morales for working out the test case, and to Ramiro and Jannis for their help on the fix.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13250 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 21e84194b5bab63f60f5d9f39d4c5ba5b1bbb5d7 1 parent b29b0f8
Russell Keith-Magee authored May 13, 2010

Showing 22 changed files with 191 additions and 15 deletions. Show diff stats Hide diff stats

  1. 5  django/views/i18n.py
  2. 12  tests/regressiontests/admin_views/tests.py
  3. 1  tests/regressiontests/views/app1/__init__.py
  4. BIN  tests/regressiontests/views/app1/locale/fr/LC_MESSAGES/djangojs.mo
  5. 20  tests/regressiontests/views/app1/locale/fr/LC_MESSAGES/djangojs.po
  6. 1  tests/regressiontests/views/app2/__init__.py
  7. BIN  tests/regressiontests/views/app2/locale/fr/LC_MESSAGES/djangojs.mo
  8. 20  tests/regressiontests/views/app2/locale/fr/LC_MESSAGES/djangojs.po
  9. 1  tests/regressiontests/views/app3/__init__.py
  10. BIN  tests/regressiontests/views/app3/locale/es_AR/LC_MESSAGES/djangojs.mo
  11. 20  tests/regressiontests/views/app3/locale/es_AR/LC_MESSAGES/djangojs.po
  12. 1  tests/regressiontests/views/app4/__init__.py
  13. BIN  tests/regressiontests/views/app4/locale/es_AR/LC_MESSAGES/djangojs.mo
  14. 20  tests/regressiontests/views/app4/locale/es_AR/LC_MESSAGES/djangojs.po
  15. BIN  tests/regressiontests/views/locale/es/LC_MESSAGES/djangojs.mo
  16. 8  tests/regressiontests/views/locale/es/LC_MESSAGES/djangojs.po
  17. BIN  tests/regressiontests/views/locale/fr/LC_MESSAGES/djangojs.mo
  18. 8  tests/regressiontests/views/locale/fr/LC_MESSAGES/djangojs.po
  19. BIN  tests/regressiontests/views/locale/ru/LC_MESSAGES/djangojs.mo
  20. 8  tests/regressiontests/views/locale/ru/LC_MESSAGES/djangojs.po
  21. 69  tests/regressiontests/views/tests/i18n.py
  22. 12  tests/regressiontests/views/urls.py
5  django/views/i18n.py
@@ -213,13 +213,16 @@ def javascript_catalog(request, domain='djangojs', packages=None):
213 213
         if en_catalog_missing:
214 214
             t = {}
215 215
         else:
  216
+            locale_t = {}
216 217
             for path in paths:
217 218
                 try:
218 219
                     catalog = gettext_module.translation(domain, path, [locale])
219 220
                 except IOError:
220 221
                     catalog = None
221 222
                 if catalog is not None:
222  
-                    t = catalog._catalog
  223
+                    locale_t.update(catalog._catalog)
  224
+            if locale_t:
  225
+                t = locale_t
223 226
     src = [LibHead]
224 227
     plural = None
225 228
     if '' in t:
12  tests/regressiontests/admin_views/tests.py
@@ -4,7 +4,6 @@
4 4
 import datetime
5 5
 from django.conf import settings
6 6
 from django.core.files import temp as tempfile
7  
-from django.test import TestCase
8 7
 from django.contrib.auth import admin # Register auth models with the admin.
9 8
 from django.contrib.auth.models import User, Permission, UNUSABLE_PASSWORD
10 9
 from django.contrib.contenttypes.models import ContentType
@@ -13,15 +12,16 @@
13 12
 from django.contrib.admin.util import quote
14 13
 from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
15 14
 from django.forms.util import ErrorList
  15
+from django.test import TestCase
16 16
 from django.utils import formats
17 17
 from django.utils.cache import get_max_age
  18
+from django.utils.encoding import iri_to_uri
18 19
 from django.utils.html import escape
19 20
 from django.utils.translation import get_date_formats, activate, deactivate
20  
-from django.utils.encoding import iri_to_uri
21 21
 
22 22
 # local test models
23 23
 from models import Article, BarAccount, CustomArticle, EmptyModel, \
24  
-    ExternalSubscriber, FooAccount, Gallery, ModelWithStringPrimaryKey, \
  24
+    FooAccount, Gallery, ModelWithStringPrimaryKey, \
25 25
     Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast, \
26 26
     Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit, \
27 27
     Category, Post, Plot, FunkyTag
@@ -36,9 +36,11 @@ class AdminViewBasicTest(TestCase):
36 36
     urlbit = 'admin'
37 37
 
38 38
     def setUp(self):
  39
+        self.old_language_code = settings.LANGUAGE_CODE
39 40
         self.client.login(username='super', password='secret')
40 41
 
41 42
     def tearDown(self):
  43
+        settings.LANGUAGE_CODE = self.old_language_code
42 44
         self.client.logout()
43 45
 
44 46
     def testTrailingSlashRequired(self):
@@ -278,26 +280,22 @@ def testI18NLanguageNonEnglishDefault(self):
278 280
         if the default language is non-English but the selected language
279 281
         is English. See #13388 and #3594 for more details.
280 282
         """
281  
-        old_language_code = settings.LANGUAGE_CODE
282 283
         settings.LANGUAGE_CODE = 'fr'
283 284
         activate('en-us')
284 285
         response = self.client.get('/test_admin/admin/jsi18n/')
285 286
         self.assertNotContains(response, 'Choisir une heure')
286 287
         deactivate()
287  
-        settings.LANGUAGE_CODE = old_language_code
288 288
 
289 289
     def testI18NLanguageNonEnglishFallback(self):
290 290
         """
291 291
         Makes sure that the fallback language is still working properly
292 292
         in cases where the selected language cannot be found.
293 293
         """
294  
-        old_language_code = settings.LANGUAGE_CODE
295 294
         settings.LANGUAGE_CODE = 'fr'
296 295
         activate('none')
297 296
         response = self.client.get('/test_admin/admin/jsi18n/')
298 297
         self.assertContains(response, 'Choisir une heure')
299 298
         deactivate()
300  
-        settings.LANGUAGE_CODE = old_language_code
301 299
 
302 300
 
303 301
 class SaveAsTests(TestCase):
1  tests/regressiontests/views/app1/__init__.py
... ...
@@ -0,0 +1 @@
  1
+#
BIN  tests/regressiontests/views/app1/locale/fr/LC_MESSAGES/djangojs.mo
Binary file not shown
20  tests/regressiontests/views/app1/locale/fr/LC_MESSAGES/djangojs.po
... ...
@@ -0,0 +1,20 @@
  1
+# SOME DESCRIPTIVE TITLE.
  2
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
  3
+# This file is distributed under the same license as the PACKAGE package.
  4
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
  5
+#
  6
+#, fuzzy
  7
+msgid ""
  8
+msgstr ""
  9
+"Project-Id-Version: PACKAGE VERSION\n"
  10
+"Report-Msgid-Bugs-To: \n"
  11
+"POT-Creation-Date: 2007-09-15 19:15+0200\n"
  12
+"PO-Revision-Date: 2010-05-12 12:41-0300\n"
  13
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
  14
+"Language-Team: LANGUAGE <LL@li.org>\n"
  15
+"MIME-Version: 1.0\n"
  16
+"Content-Type: text/plain; charset=UTF-8\n"
  17
+"Content-Transfer-Encoding: 8bit\n"
  18
+
  19
+msgid "this app1 string is to be translated"
  20
+msgstr "il faut traduire cette chaîne de caractères de app1"
1  tests/regressiontests/views/app2/__init__.py
... ...
@@ -0,0 +1 @@
  1
+#
BIN  tests/regressiontests/views/app2/locale/fr/LC_MESSAGES/djangojs.mo
Binary file not shown
20  tests/regressiontests/views/app2/locale/fr/LC_MESSAGES/djangojs.po
... ...
@@ -0,0 +1,20 @@
  1
+# SOME DESCRIPTIVE TITLE.
  2
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
  3
+# This file is distributed under the same license as the PACKAGE package.
  4
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
  5
+#
  6
+#, fuzzy
  7
+msgid ""
  8
+msgstr ""
  9
+"Project-Id-Version: PACKAGE VERSION\n"
  10
+"Report-Msgid-Bugs-To: \n"
  11
+"POT-Creation-Date: 2007-09-15 19:15+0200\n"
  12
+"PO-Revision-Date: 2010-05-12 22:05-0300\n"
  13
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
  14
+"Language-Team: LANGUAGE <LL@li.org>\n"
  15
+"MIME-Version: 1.0\n"
  16
+"Content-Type: text/plain; charset=UTF-8\n"
  17
+"Content-Transfer-Encoding: 8bit\n"
  18
+
  19
+msgid "this app2 string is to be translated"
  20
+msgstr "il faut traduire cette chaîne de caractères de app2"
1  tests/regressiontests/views/app3/__init__.py
... ...
@@ -0,0 +1 @@
  1
+#
BIN  tests/regressiontests/views/app3/locale/es_AR/LC_MESSAGES/djangojs.mo
Binary file not shown
20  tests/regressiontests/views/app3/locale/es_AR/LC_MESSAGES/djangojs.po
... ...
@@ -0,0 +1,20 @@
  1
+# SOME DESCRIPTIVE TITLE.
  2
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
  3
+# This file is distributed under the same license as the PACKAGE package.
  4
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
  5
+#
  6
+#, fuzzy
  7
+msgid ""
  8
+msgstr ""
  9
+"Project-Id-Version: PACKAGE VERSION\n"
  10
+"Report-Msgid-Bugs-To: \n"
  11
+"POT-Creation-Date: 2007-09-15 19:15+0200\n"
  12
+"PO-Revision-Date: 2010-05-12 12:41-0300\n"
  13
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
  14
+"Language-Team: LANGUAGE <LL@li.org>\n"
  15
+"MIME-Version: 1.0\n"
  16
+"Content-Type: text/plain; charset=UTF-8\n"
  17
+"Content-Transfer-Encoding: 8bit\n"
  18
+
  19
+msgid "il faut traduire cette chaîne de caractères de app3"
  20
+msgstr "este texto de app3 debe ser traducido"
1  tests/regressiontests/views/app4/__init__.py
... ...
@@ -0,0 +1 @@
  1
+#
BIN  tests/regressiontests/views/app4/locale/es_AR/LC_MESSAGES/djangojs.mo
Binary file not shown
20  tests/regressiontests/views/app4/locale/es_AR/LC_MESSAGES/djangojs.po
... ...
@@ -0,0 +1,20 @@
  1
+# SOME DESCRIPTIVE TITLE.
  2
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
  3
+# This file is distributed under the same license as the PACKAGE package.
  4
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
  5
+#
  6
+#, fuzzy
  7
+msgid ""
  8
+msgstr ""
  9
+"Project-Id-Version: PACKAGE VERSION\n"
  10
+"Report-Msgid-Bugs-To: \n"
  11
+"POT-Creation-Date: 2007-09-15 19:15+0200\n"
  12
+"PO-Revision-Date: 2010-05-12 12:41-0300\n"
  13
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
  14
+"Language-Team: LANGUAGE <LL@li.org>\n"
  15
+"MIME-Version: 1.0\n"
  16
+"Content-Type: text/plain; charset=UTF-8\n"
  17
+"Content-Transfer-Encoding: 8bit\n"
  18
+
  19
+msgid "il faut traduire cette chaîne de caractères de app4"
  20
+msgstr "este texto de app4 debe ser traducido"
BIN  tests/regressiontests/views/locale/es/LC_MESSAGES/djangojs.mo
Binary file not shown
8  tests/regressiontests/views/locale/es/LC_MESSAGES/djangojs.po
@@ -9,7 +9,7 @@ msgstr ""
9 9
 "Project-Id-Version: PACKAGE VERSION\n"
10 10
 "Report-Msgid-Bugs-To: \n"
11 11
 "POT-Creation-Date: 2007-09-15 16:45+0200\n"
12  
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
  12
+"PO-Revision-Date: 2010-05-12 12:57-0300\n"
13 13
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 14
 "Language-Team: LANGUAGE <LL@li.org>\n"
15 15
 "MIME-Version: 1.0\n"
@@ -18,4 +18,8 @@ msgstr ""
18 18
 
19 19
 #: media/js/translate.js:1
20 20
 msgid "this is to be translated"
21  
-msgstr "esto tiene que ser traducido"
  21
+msgstr "esto tiene que ser traducido"
  22
+
  23
+
  24
+msgid "Choose a time"
  25
+msgstr "Elige una hora"
BIN  tests/regressiontests/views/locale/fr/LC_MESSAGES/djangojs.mo
Binary file not shown
8  tests/regressiontests/views/locale/fr/LC_MESSAGES/djangojs.po
@@ -9,7 +9,7 @@ msgstr ""
9 9
 "Project-Id-Version: PACKAGE VERSION\n"
10 10
 "Report-Msgid-Bugs-To: \n"
11 11
 "POT-Creation-Date: 2007-09-15 19:15+0200\n"
12  
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
  12
+"PO-Revision-Date: 2010-05-12 12:41-0300\n"
13 13
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 14
 "Language-Team: LANGUAGE <LL@li.org>\n"
15 15
 "MIME-Version: 1.0\n"
@@ -17,4 +17,8 @@ msgstr ""
17 17
 "Content-Transfer-Encoding: 8bit\n"
18 18
 
19 19
 msgid "this is to be translated"
20  
-msgstr "il faut le traduire"
  20
+msgstr "il faut le traduire"
  21
+
  22
+
  23
+msgid "Choose a time"
  24
+msgstr "Choisir une heure"
BIN  tests/regressiontests/views/locale/ru/LC_MESSAGES/djangojs.mo
Binary file not shown
8  tests/regressiontests/views/locale/ru/LC_MESSAGES/djangojs.po
@@ -9,7 +9,7 @@ msgstr ""
9 9
 "Project-Id-Version: PACKAGE VERSION\n"
10 10
 "Report-Msgid-Bugs-To: \n"
11 11
 "POT-Creation-Date: 2007-09-15 16:45+0200\n"
12  
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
  12
+"PO-Revision-Date: 2010-05-12 12:57-0300\n"
13 13
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14 14
 "Language-Team: LANGUAGE <LL@li.org>\n"
15 15
 "MIME-Version: 1.0\n"
@@ -17,4 +17,8 @@ msgstr ""
17 17
 "Content-Transfer-Encoding: 8bit\n"
18 18
 
19 19
 msgid "this is to be translated"
20  
-msgstr "перевод"
  20
+msgstr "перевод"
  21
+
  22
+
  23
+msgid "Choose a time"
  24
+msgstr "Выберите время"
69  tests/regressiontests/views/tests/i18n.py
... ...
@@ -1,8 +1,9 @@
  1
+# -*- coding:utf-8 -*-
1 2
 import gettext
2 3
 
3 4
 from django.conf import settings
4 5
 from django.test import TestCase
5  
-from django.utils.translation import activate
  6
+from django.utils.translation import activate, deactivate
6 7
 from django.utils.text import javascript_quote
7 8
 
8 9
 from regressiontests.views.urls import locale_dir
@@ -30,6 +31,7 @@ def test_jsi18n(self):
30 31
             # javascript_quote is used to be able to check unicode strings
31 32
             self.assertContains(response, javascript_quote(trans_txt), 1)
32 33
 
  34
+
33 35
 class JsI18NTests(TestCase):
34 36
     """
35 37
     Tests django views in django/views/i18n.py that need to change
@@ -66,3 +68,68 @@ def test_jsi18n_fallback_language(self):
66 68
         activate('fi')
67 69
         response = self.client.get('/views/jsi18n/')
68 70
         self.assertContains(response, 'il faut le traduire')
  71
+
  72
+    def testI18NLanguageNonEnglishDefault(self):
  73
+        """
  74
+        Check if the Javascript i18n view returns an empty language catalog
  75
+        if the default language is non-English but the selected language
  76
+        is English. See #13388 and #3594 for more details.
  77
+        """
  78
+        settings.LANGUAGE_CODE = 'fr'
  79
+        activate('en-us')
  80
+        response = self.client.get('/views/jsi18n/')
  81
+        self.assertNotContains(response, 'Choisir une heure')
  82
+        deactivate()
  83
+
  84
+    def testI18NLanguageNonEnglishFallback(self):
  85
+        """
  86
+        Makes sure that the fallback language is still working properly
  87
+        in cases where the selected language cannot be found.
  88
+        """
  89
+        settings.LANGUAGE_CODE = 'fr'
  90
+        activate('none')
  91
+        response = self.client.get('/views/jsi18n/')
  92
+        self.assertContains(response, 'Choisir une heure')
  93
+        deactivate()
  94
+
  95
+
  96
+class JsI18NTestsMultiPackage(TestCase):
  97
+    """
  98
+    Tests for django views in django/views/i18n.py that need to change
  99
+    settings.LANGUAGE_CODE and merge JS translation from several packages.
  100
+    """
  101
+
  102
+    def setUp(self):
  103
+        self.old_language_code = settings.LANGUAGE_CODE
  104
+        self.old_installed_apps = settings.INSTALLED_APPS
  105
+
  106
+    def tearDown(self):
  107
+        settings.LANGUAGE_CODE = self.old_language_code
  108
+        settings.INSTALLED_APPS = self.old_installed_apps
  109
+
  110
+    def testI18NLanguageEnglishDefault(self):
  111
+        """
  112
+        Check if the JavaScript i18n view returns a complete language catalog
  113
+        if the default language is en-us, the selected language has a
  114
+        translation available and a catalog composed by djangojs domain
  115
+        translations of multiple Python packages is requested. See #13388,
  116
+        #3594 and #13514 for more details.
  117
+        """
  118
+        settings.LANGUAGE_CODE = 'en-us'
  119
+        settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + ['regressiontests.views.app1', 'regressiontests.views.app2']
  120
+        activate('fr')
  121
+        response = self.client.get('/views/jsi18n_multi_packages1/')
  122
+        self.assertContains(response, javascript_quote('il faut traduire cette chaîne de caractères de app1'))
  123
+        deactivate()
  124
+
  125
+    def testI18NDifferentNonEnLangs(self):
  126
+        """
  127
+        Similar to above but with neither default or requested language being
  128
+        English.
  129
+        """
  130
+        settings.LANGUAGE_CODE = 'fr'
  131
+        settings.INSTALLED_APPS = list(settings.INSTALLED_APPS) + ['regressiontests.views.app3', 'regressiontests.views.app4']
  132
+        activate('es-ar')
  133
+        response = self.client.get('/views/jsi18n_multi_packages2/')
  134
+        self.assertContains(response, javascript_quote('este texto de app3 debe ser traducido'))
  135
+        deactivate()
12  tests/regressiontests/views/urls.py
@@ -16,6 +16,16 @@
16 16
     'packages': ('regressiontests.views',),
17 17
 }
18 18
 
  19
+js_info_dict_multi_packages1 = {
  20
+    'domain': 'djangojs',
  21
+    'packages': ('regressiontests.views.app1', 'regressiontests.views.app2'),
  22
+}
  23
+
  24
+js_info_dict_multi_packages2 = {
  25
+    'domain': 'djangojs',
  26
+    'packages': ('regressiontests.views.app3', 'regressiontests.views.app4'),
  27
+}
  28
+
19 29
 date_based_info_dict = {
20 30
     'queryset': Article.objects.all(),
21 31
     'date_field': 'date_created',
@@ -36,6 +46,8 @@
36 46
     # i18n views
37 47
     (r'^i18n/', include('django.conf.urls.i18n')),
38 48
     (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
  49
+    (r'^jsi18n_multi_packages1/$', 'django.views.i18n.javascript_catalog', js_info_dict_multi_packages1),
  50
+    (r'^jsi18n_multi_packages2/$', 'django.views.i18n.javascript_catalog', js_info_dict_multi_packages2),
39 51
 
40 52
     # Static views
41 53
     (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': media_dir}),

0 notes on commit 21e8419

Please sign in to comment.
Something went wrong with that request. Please try again.