diff --git a/apps/navigation/api.py b/apps/navigation/api.py index 2845d684ca..e43df44906 100644 --- a/apps/navigation/api.py +++ b/apps/navigation/api.py @@ -49,14 +49,16 @@ class Link(object): self.conditional_disable = conditional_disable self.description = description self.dont_mark_active = dont_mark_active - self.children_view_regex = children_view_regex or [] self.klass = klass self.keep_query = keep_query self.conditional_highlight = conditional_highlight # Used by dynamic sources self.children_views = children_views or [] self.children_classes = children_classes or [] + self.children_url_regex = children_url_regex or [] + self.children_view_regex = children_view_regex or [] def resolve(self, context): + # TODO: don't calculate these if passed in an argument request = Variable('request').resolve(context) current_path = request.META['PATH_INFO'] current_view = resolve_to_name(current_path) @@ -88,7 +90,6 @@ class Link(object): if self.view: if not self.dont_mark_active: - #new_link['active'] = link['view'] == current_view resolved_link.active = self.view == current_view try: @@ -104,41 +105,32 @@ class Link(object): resolved_link.error = exc elif self.url: if not self.dont_mark_active: - #new_link['active'] = link['url'] == current_path resolved_link.url.active = self.url == current_path if kwargs: - #new_link['url'] = link['url'] % kwargs resolved_link.url = self.url % kwargs else: - #new_link['url'] = link['url'] % args resolved_link.url = self.url % args if link.keep_query: - #new_link['url'] = urlquote(new_link['url'], parsed_query_string) - resolved_link.url = urlquote(resolved_link.url, parsed_query_string) + resolved_link.url = u'%s?%s' % (urlquote(resolved_link.url), urlencode(parsed_query_string, doseq=True)) else: - #new_link['active'] = False resolved_link.active = False if self.conditional_highlight: - #new_link['active'] = link['conditional_highlight'](context) resolved_link.active = self.conditional_highlight(context) if self.conditional_disable: - #new_link['disabled'] = link['conditional_disable'](context) resolved_link.disabled = self.conditional_disable(context) else: - #new_link['disabled'] = False resolved_link.disabled = False if current_view in self.children_views: - #new_link['active'] = True resolved_link.active = True - #for child_url_regex in link.get('children_url_regex', []): - # if re.compile(child_url_regex).match(current_path.lstrip('/')): - # #new_link['active'] = True - # resolved_link.active = True + # TODO: eliminate url_regexes and use new tree base main menu + for child_url_regex in self.children_url_regex: + if re.compile(child_url_regex).match(current_path.lstrip('/')): + resolved_link.active = True for children_view_regex in self.children_view_regex: if re.compile(children_view_regex).match(current_view): @@ -206,16 +198,19 @@ def register_multi_item_links(sources, links, menu_name=None): multi_object_navigation[menu_name].setdefault(source, {'links': []}) multi_object_navigation[menu_name][source]['links'].extend(links) - -def get_context_object_navigation_links(context, menu_name=None, links_dict=link_binding): +#TODO: new name: get_context_navigation_links, get_navigation_links_for_context +def get_context_object_navigation_links(context, menu_name=None, links_dict=link_binding):#, object_variable_name=None): request = Variable('request').resolve(context) current_path = request.META['PATH_INFO'] current_view = resolve_to_name(current_path) - context_links = [] + context_links = {} # Don't fudge with the original global dictionary + # TODO: fix this links_dict = links_dict.copy() + # TODO: doesn't appear to be used + ''' try: """ Override the navigation links dictionary with the provided @@ -226,8 +221,10 @@ def get_context_object_navigation_links(context, menu_name=None, links_dict=link return [link.resolve(context) for link in navigation_object_links] except VariableDoesNotExist: pass - + ''' # TODO: who uses this? Remove if no one. + # Dynamic sources + # TODO: improve name to 'injected...' try: """ Check for and inject a temporary navigation dictionary @@ -239,15 +236,24 @@ def get_context_object_navigation_links(context, menu_name=None, links_dict=link pass try: - for link in links_dict[menu_name][current_view]['links']: - context_links.append(link.resolve(context)) + view_links = links_dict[menu_name][current_view]['links'] + if view_links: + context_links.setdefault(None, []) + + for link in view_links: + context_links[None].append(link.resolve(context)) except KeyError: pass - for resolved_object in get_navigation_objects(context): + for resolved_object, object_properties in get_navigation_objects(context).items(): try: - for link in links_dict[menu_name][type(resolved_object['object'])]['links']: - context_links.append(link.resolve(context)) + resolved_object_reference = resolved_object + object_links = links_dict[menu_name][type(resolved_object_reference)]['links'] + if object_links: + context_links.setdefault(resolved_object_reference, []) + + for link in object_links: + context_links[resolved_object_reference].append(link.resolve(context)) except KeyError: pass diff --git a/apps/navigation/templatetags/navigation_tags.py b/apps/navigation/templatetags/navigation_tags.py index 61d3472715..0ba20469d7 100644 --- a/apps/navigation/templatetags/navigation_tags.py +++ b/apps/navigation/templatetags/navigation_tags.py @@ -46,13 +46,6 @@ class GetNavigationLinks(Node): def render(self, context): menu_name = resolve_template_variable(context, self.menu_name) context[self.var_name] = get_context_object_navigation_links(context, menu_name, links_dict=self.links_dict) - logger.debug('link_list: %s' % get_context_object_navigation_links(context, menu_name, links_dict=self.links_dict)) - object_list = get_navigation_objects(context) - logger.debug('object_list: %s' % object_list) - - # TODO: why only one navigation_object - if object_list: - context['navigation_object'] = object_list[0]['object'] return '' @@ -72,13 +65,15 @@ def get_object_navigation_links(parser, token): @register.inclusion_tag('generic_navigation.html', takes_context=True) def object_navigation_template(context): new_context = copy.copy(context) - new_context.update({ - 'horizontal': True, - 'object_navigation_links': get_context_object_navigation_links(context) - }) + + for object_reference, object_links in get_context_object_navigation_links(context).items(): + new_context.update({ + 'horizontal': True, + 'links': object_links + }) + return new_context - - + @register.tag def get_multi_item_links(parser, token): tag_name, arg = token.contents.split(None, 1) @@ -92,9 +87,14 @@ def get_multi_item_links(parser, token): @register.inclusion_tag('generic_form_instance.html', takes_context=True) def get_multi_item_links_form(context): + logger.debug('starting') + links = [] + for object_reference, object_links in get_context_object_navigation_links(context, links_dict=multi_object_navigation).items(): + links.extend(object_links) + new_context = copy.copy(context) new_context.update({ - 'form': MultiItemForm(actions=[(link.url, link.text) for link in get_context_object_navigation_links(context, links_dict=multi_object_navigation)]), + 'form': MultiItemForm(actions=[(link.url, link.text) for link in links]), 'title': _(u'Selected item actions:'), 'form_action': reverse('multi_object_action_view'), 'submit_method': 'get', diff --git a/apps/navigation/utils.py b/apps/navigation/utils.py index 923af8112e..a720883e03 100644 --- a/apps/navigation/utils.py +++ b/apps/navigation/utils.py @@ -8,51 +8,81 @@ from django.template import (TemplateSyntaxError, Library, VariableDoesNotExist, Node, Variable) from django.utils.text import unescape_string_literal -#__all__ = ('resolve_to_name',) logger = logging.getLogger(__name__) def get_navigation_objects(context): - object_list = [] + objects = {} + + try: + indirect_reference_list = Variable('navigation_object_list').resolve(context) + except VariableDoesNotExist: + pass + else: + logger.debug('found: navigation_object_list') + for indirect_reference in indirect_reference_list: + try: + resolved_object = Variable(indirect_reference['object']).resolve(context) + except VariableDoesNotExist: + resolved_object = None + else: + objects.setdefault(resolved_object, {}) + objects[resolved_object]['label'] = indirect_reference.get('object_name') + + try: + indirect_reference = Variable('navigation_object_name').resolve(context) + except VariableDoesNotExist: + pass + else: + logger.debug('found: navigation_object_name') + try: + object_label = Variable('object_name').resolve(context) + except VariableDoesNotExist: + object_label = None + finally: + try: + resolved_object = Variable(indirect_reference).resolve(context) + except VariableDoesNotExist: + resolved_object = None + + objects.setdefault(resolved_object, {}) + objects[resolved_object]['label'] = object_label + + try: + indirect_reference = Variable('list_object_variable_name').resolve(context) + except VariableDoesNotExist: + pass + else: + logger.debug('found renamed list object') + try: + object_label = Variable('object_name').resolve(context) + except VariableDoesNotExist: + object_label = None + finally: + try: + resolved_object = Variable(indirect_reference).resolve(context) + except VariableDoesNotExist: + resolved_object = None + else: + objects.setdefault(resolved_object, {}) + objects[resolved_object]['label'] = object_label - # Try a simple 'object' search first, for lists templates try: resolved_object = Variable('object').resolve(context) except VariableDoesNotExist: - try: - object_name_list = Variable('navigation_object_list').resolve(context) - except VariableDoesNotExist: - try: - object_name_list = [{'object': Variable('navigation_object_name').resolve(context)}] - except VariableDoesNotExist: - #try: - # object_name_list = [{'object': Variable('list_object_variable_name').resolve(context)}] - #except VariableDoesNotExist: - return [] - #object_name_list = [{'object': 'object'}] - #logger.debug('none found, falling back to "object"') - #else: - # logger.debug('found: list_object_variable_name') - else: - logger.debug('found: navigation_object_name') - else: - logger.debug('found: navigation_object_list') + pass else: logger.debug('found single object') - return [{'object': resolved_object}]#, 'object_name': 'object'}] - - logger.debug('object_name_list: %s' % object_name_list) - - for object_name in object_name_list: try: - resolved_object = Variable(object_name['object']).resolve(context) + object_label = Variable('object_name').resolve(context) except VariableDoesNotExist: - resolved_object = None - - object_list.append({'object': resolved_object})#, 'object_name': 'qwe'}) + object_label = None + finally: + objects.setdefault(resolved_object, {}) + objects[resolved_object]['label'] = object_label - logger.debug('object_list: %s' % object_list) - return object_list + logger.debug('objects: %s' % objects) + return objects def resolve_template_variable(context, name):