--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -1,4 +1,5 @@
import logging
+from collections import Counter, OrderedDict
from datetime import datetime
from tg import config
@@ -418,7 +419,8 @@
if app.is_visible_to(c.user):
for sm in app.main_menu():
entry = sm.bind_app(app)
- entry.ui_icon='tool-%s' % ac.tool_name.lower()
+ entry.tool_name = ac.tool_name
+ entry.ui_icon = 'tool-%s' % entry.tool_name.lower()
ordinal = int(ac.options.get('ordinal', 0)) + delta_ordinal
if ordinal > max_ordinal:
max_ordinal = ordinal
@@ -430,6 +432,39 @@
entries = sorted(entries, key=lambda e: e['ordinal'])
return [e['entry'] for e in entries]
+
+ def grouped_navbar_entries(self):
+ """Return a ``allura.app.SitemapEntry`` list suitable for rendering
+ the project navbar with tools grouped together by tool type.
+ """
+ # get orginal (non-grouped) navbar entries
+ sitemap = self.sitemap()
+ # ordered dict to preserve the orginal ordering of tools
+ grouped_nav = OrderedDict()
+ # count how many tools of each type we have
+ counts = Counter([e.tool_name.lower() for e in sitemap if e.tool_name])
+ for e in sitemap:
+ # if it's not a tool, add to navbar and continue
+ if not e.tool_name:
+ grouped_nav[id(e)] = e
+ continue
+ tool_name = e.tool_name.lower()
+ # tool of a type we don't have in the navbar yet
+ if tool_name not in grouped_nav:
+ # there's more than one tool of this type
+ if counts.get(tool_name, 1) > 1:
+ # change label to be the tool name (type)
+ e.label = tool_name.capitalize()
+ # add tool url to list of urls that will match this nav entry
+ e.matching_urls.append(e.url)
+ # change url to point to tool list page
+ e.url = self.url() + '_list/' + tool_name
+ grouped_nav[tool_name] = e
+ else:
+ # already have a tool of this type in the nav; add this tool's
+ # url to the list of urls that match this nav entry
+ grouped_nav[tool_name].matching_urls.append(e.url)
+ return grouped_nav.values()
def parent_iter(self):
yield self