Repository: django-cms/django-cms

Issue:
toolbar name dependent on order of get_or_create_menu() calls
[As documented](http://django-cms.readthedocs.org/en/develop/extending_cms/extending_page_title.html), `self.toolbar.get_or_create_menu('page')` can result in the menu's `verbose_name` being `None` if that call is invoked before a call that includes the menu's name, like `self.toolbar.get_or_create_menu('page', _('Page')`.



Discussion:
(affects `side` and `position` arguments as well)

Could you check in latest develop?
#2751 should have fixed it

I can't reproduce (although I'm not sure the failure was deterministic in the first place), but we can close this for now, thanks.

It happened again on latest develop. You can see in [this code](https://github.com/divio/django-cms/blob/develop/cms/toolbar/toolbar.py#L102) that if the menu key is already in `self.menus`, it'll be returned as-is, ignoring the arguments of subsequent calls. So if `self.toolbar.get_or_create_menu('page')` runs before a call that includes the name: `self.toolbar.get_or_create_menu('page', _('Page')` the menu will be named `None`.

according to

https://github.com/divio/django-cms/blob/develop/cms/toolbar/items.py#L236

is verbose name required. So `self.toolbar.get_or_create_menu('page')` should fail anyway.... no?

Sorry, I've linked to the wrong instance of `get_or_create_menu()`. I've corrected it in the comment above.

Ok an easy fix would be that if the verbose_name is something we set it again on the returned menu


Resolving patch:
diff --git a/cms/toolbar/toolbar.py b/cms/toolbar/toolbar.py
--- a/cms/toolbar/toolbar.py
+++ b/cms/toolbar/toolbar.py
@@ -105,7 +105,15 @@ def get_menu(self, key, verbose_name=None, side=LEFT, position=None):
     def get_or_create_menu(self, key, verbose_name=None, side=LEFT, position=None):
         self.populate()
         if key in self.menus:
-            return self.menus[key]
+            menu = self.menus[key]
+            if verbose_name:
+                menu.name = verbose_name
+            if menu.side != side:
+                menu.side = side
+            if position:
+                self.remove_item(menu)
+                self.add_item(menu, position=position)
+            return menu
         menu = Menu(verbose_name, self.csrf_token, side=side)
         self.menus[key] = menu
         self.add_item(menu, position=position)


Test patch:
diff --git a/cms/tests/toolbar.py b/cms/tests/toolbar.py
--- a/cms/tests/toolbar.py
+++ b/cms/tests/toolbar.py
@@ -290,6 +290,18 @@ def test_get_alphabetical_insert_position(self):
         beta_position = admin_menu.get_alphabetical_insert_position('menu-beta', SubMenu)
         self.assertEqual(beta_position, gamma_position)
 
+    def test_out_of_order(self):
+        page = create_page("toolbar-page", "nav_playground.html", "en",
+                           published=True)
+        request = self.get_page_request(page, self.get_staff(), '/')
+        toolbar = CMSToolbar(request)
+        menu1 = toolbar.get_or_create_menu("test")
+        menu2 = toolbar.get_or_create_menu("test", "Test", side=toolbar.RIGHT, position=2)
+
+        self.assertEqual(menu1, menu2)
+        self.assertEqual(menu1.name, 'Test')
+        self.assertEqual(len(toolbar.get_right_items()), 1)
+
     def test_page_create_redirect(self):
         superuser = self.get_superuser()
         create_page("home", "nav_playground.html", "en",