Repository: django-cms/django-cms

Issue:
toolbar items not internationalized
See screenshot:

![screen shot 2013-09-19 at 5 31 11 pm](https://f.cloud.github.com/assets/141122/1171426/0579f9d0-2106-11e3-8ca5-9d9c5f915891.png)



Discussion:
Thanks, will include this in the next update, This concerns the ckeditor and not the cms :)

It does concern the toolbar too. See at the top. Shouldn't the toolbar items be in Japanese if I browse the site in Japanese?

Yeah the "cancel" is also missing, I'll check the entire thing if there are missing {% trans...
The toolbar should also always stay at the language you choose from the "User Settings" on the Toolbar

**Edit:** all frontend values are set through the backend, so I guess the translations are missing

The issue seems to be:

UserSettings is always created with the language set to the language the toolbar is first viewed in.

Allow setting UserSettings language to None, possibly setting it to None as default or keep as is?


Resolving patch:
diff --git a/cms/middleware/toolbar.py b/cms/middleware/toolbar.py
--- a/cms/middleware/toolbar.py
+++ b/cms/middleware/toolbar.py
@@ -5,6 +5,7 @@
 from cms.plugin_pool import plugin_pool
 from cms.toolbar.toolbar import CMSToolbar
 from cms.utils.compat.dj import force_unicode
+from cms.utils.i18n import force_language
 from menus.menu_pool import menu_pool
 from django.http import HttpResponse
 from django.template.loader import render_to_string
@@ -21,15 +22,17 @@ def toolbar_plugin_processor(instance, placeholder, rendered_content, original_c
         childs = [plugin_pool.get_plugin(cls) for cls in plugin.get_child_classes(placeholder, page)]
         # Builds the list of dictionaries containing module, name and value for the plugin dropdowns
         child_plugin_classes = get_toolbar_plugin_struct(childs, placeholder.slot, placeholder.page, parent=plugin_class)
-    data = {
-        'instance': instance,
-        'rendered_content': rendered_content,
-        'child_plugin_classes': child_plugin_classes,
-        'edit_url': placeholder.get_edit_url(instance.pk),
-        'add_url': placeholder.get_add_url(),
-        'delete_url': placeholder.get_delete_url(instance.pk),
-        'move_url': placeholder.get_move_url(),
-    }
+    request = original_context['request']
+    with force_language(request.toolbar.toolbar_language):
+        data = {
+            'instance': instance,
+            'rendered_content': rendered_content,
+            'child_plugin_classes': child_plugin_classes,
+            'edit_url': placeholder.get_edit_url(instance.pk),
+            'add_url': placeholder.get_add_url(),
+            'delete_url': placeholder.get_delete_url(instance.pk),
+            'move_url': placeholder.get_move_url(),
+        }
     original_context.update(data)
     output = render_to_string(instance.get_plugin_class().frontend_edit_template, original_context)
     original_context.pop()
diff --git a/cms/templatetags/cms_tags.py b/cms/templatetags/cms_tags.py
--- a/cms/templatetags/cms_tags.py
+++ b/cms/templatetags/cms_tags.py
@@ -643,52 +643,54 @@ def _get_editable_context(self, context, instance, language, edit_fields,
         """
         Populate the contex with the requested attributes to trigger the changeform
         """
-        extra_context = {}
-        if editmode:
-            instance.get_plugin_name = u"%s %s" % (smart_text(_('Edit')), smart_text(instance._meta.verbose_name))
-        else:
-            instance.get_plugin_name = u"%s %s" % (smart_text(_('Add')), smart_text(instance._meta.verbose_name))
-            extra_context['attribute_name'] = 'add'
-        extra_context['instance'] = instance
-        extra_context['generic'] = instance._meta
-        # view_method has the precedence and we retrieve the corresponding
-        # attribute in the instance class.
-        # If view_method refers to a method it will be called passing the
-        # request; if it's an attribute, it's stored for later use
-        if view_method:
-            method = getattr(instance, view_method)
-            if callable(method):
-                url_base = method(context['request'])
+        request = context['request']
+        with force_language(request.toolbar.toolbar_language):
+            extra_context = {}
+            if editmode:
+                instance.get_plugin_name = u"%s %s" % (smart_text(_('Edit')), smart_text(instance._meta.verbose_name))
             else:
-                url_base = method
-        else:
-            # The default view_url is the default admin changeform for the
-            # current instance
-            if not editmode:
-                view_url = 'admin:%s_%s_add' % (
-                    instance._meta.app_label, instance._meta.module_name)
-                url_base = reverse(view_url)
-            elif not edit_fields:
-                view_url = 'admin:%s_%s_change' % (
-                    instance._meta.app_label, instance._meta.module_name)
-                url_base = reverse(view_url, args=(instance.pk,))
+                instance.get_plugin_name = u"%s %s" % (smart_text(_('Add')), smart_text(instance._meta.verbose_name))
+                extra_context['attribute_name'] = 'add'
+            extra_context['instance'] = instance
+            extra_context['generic'] = instance._meta
+            # view_method has the precedence and we retrieve the corresponding
+            # attribute in the instance class.
+            # If view_method refers to a method it will be called passing the
+            # request; if it's an attribute, it's stored for later use
+            if view_method:
+                method = getattr(instance, view_method)
+                if callable(method):
+                    url_base = method(context['request'])
+                else:
+                    url_base = method
             else:
-                if not view_url:
-                    view_url = 'admin:%s_%s_edit_field' % (
+                # The default view_url is the default admin changeform for the
+                # current instance
+                if not editmode:
+                    view_url = 'admin:%s_%s_add' % (
                         instance._meta.app_label, instance._meta.module_name)
-                url_base = reverse(view_url, args=(instance.pk, language))
-                querystring['edit_fields'] = ",".join(context['edit_fields'])
-        if editmode:
-            extra_context['edit_url'] = "%s?%s" % (url_base, urlencode(querystring))
-        else:
-            extra_context['edit_url'] = "%s" % url_base
-        extra_context['refresh_page'] = True
-        # We may be outside the CMS (e.g.: an application which is not attached via Apphook)
-        # in this case we may only go back to the home page
-        if getattr(context['request'], 'current_page', None):
-            extra_context['redirect_on_close'] = context['request'].current_page.get_absolute_url(language)
-        else:
-            extra_context['redirect_on_close'] = ''
+                    url_base = reverse(view_url)
+                elif not edit_fields:
+                    view_url = 'admin:%s_%s_change' % (
+                        instance._meta.app_label, instance._meta.module_name)
+                    url_base = reverse(view_url, args=(instance.pk,))
+                else:
+                    if not view_url:
+                        view_url = 'admin:%s_%s_edit_field' % (
+                            instance._meta.app_label, instance._meta.module_name)
+                    url_base = reverse(view_url, args=(instance.pk, language))
+                    querystring['edit_fields'] = ",".join(context['edit_fields'])
+            if editmode:
+                extra_context['edit_url'] = "%s?%s" % (url_base, urlencode(querystring))
+            else:
+                extra_context['edit_url'] = "%s" % url_base
+            extra_context['refresh_page'] = True
+            # We may be outside the CMS (e.g.: an application which is not attached via Apphook)
+            # in this case we may only go back to the home page
+            if getattr(context['request'], 'current_page', None):
+                extra_context['redirect_on_close'] = context['request'].current_page.get_absolute_url(language)
+            else:
+                extra_context['redirect_on_close'] = ''
         return extra_context
 
     def _get_content(self, context, instance, attribute, language, filters):


Test patch:
diff --git a/cms/test_utils/cli.py b/cms/test_utils/cli.py
--- a/cms/test_utils/cli.py
+++ b/cms/test_utils/cli.py
@@ -205,7 +205,7 @@ def configure(db_url, **extra):
                     'LinkPlugin': 'Different Grouper'
                 },
                 'plugin_labels': {
-                    'LinkPlugin': 'Add a link'
+                    'LinkPlugin': gettext('Add a link')
                 }
             },
 
diff --git a/cms/tests/toolbar.py b/cms/tests/toolbar.py
--- a/cms/tests/toolbar.py
+++ b/cms/tests/toolbar.py
@@ -158,7 +158,7 @@ def test_markup_flash_custom_module(self):
         with self.login_user_context(superuser):
             response = self.client.get('/en/?edit')
         self.assertEquals(response.status_code, 200)
-        self.assertContains(response, 'href="LinkPlugin">Add a link')
+        self.assertContains(response, 'href="LinkPlugin">')
         self.assertContains(response, '<div class="cms_submenu-item cms_submenu-item-title"><span>Different Grouper</span>')
 
     def test_show_toolbar_to_staff(self):
@@ -242,6 +242,12 @@ def test_placeholder_name(self):
             self.assertEquals(response.status_code, 200)
             self.assertContains(response, 'PPPP')
 
+    def test_user_settings(self):
+        superuser = self.get_superuser()
+        with self.login_user_context(superuser):
+            response = self.client.get('/en/admin/cms/usersettings/')
+            self.assertEqual(response.status_code, 200)
+
 
 class EditModelTemplateTagTest(ToolbarTestBase):
     urls = 'cms.test_utils.project.placeholderapp_urls'