Skip to content

Commit

Permalink
general: match complete segments for active items
Browse files Browse the repository at this point in the history
* Uses whole segment of the URL instead of a prefix to determine active
  menu item. Currently the menu item is marked as active when there is a
  prefix match on the URL. This creates situations where multiple
  different menu items appear to be active just because they share a
  prefix. (closes #62)
  • Loading branch information
datashaman authored and lnielsen committed Dec 12, 2017
1 parent 6f316de commit 966a7c2
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ Contact us at `info@inveniosoftware.org <mailto:info@inveniosoftware.org>`_
* Nick Whyte <nick@nickwhyte.com>
* Sami Hiltunen <sami.mikael.hiltunen@cern.ch>
* Sylvain Boily <sboily@proformatique.com>
* Marlin Forbes <marlinf@datashaman.com>
22 changes: 18 additions & 4 deletions flask_menu/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
#
# This file is part of Flask-Menu
# Copyright (C) 2013, 2014, 2015, 2017 CERN.
# Copyright (C) 2013, 2014, 2015, 2017 CERN
# Copyright (C) 2017 Marlin Forbes
#
# Flask-Menu is free software; you can redistribute it and/or modify
# it under the terms of the Revised BSD License; see LICENSE file for
Expand Down Expand Up @@ -90,10 +91,23 @@ def __init__(self, name, parent):
def _active_when(self):
"""Define condition when a menu entry is active."""
matching_endpoint = request.endpoint == self._endpoint
matching_subpath = len(self.url) > 1 \
and request.path.startswith(self.url)

def segments(path):
"""Split a path into segments."""
parts = path.split('/')[1:]
if len(parts) > 0 and parts[-1] == '':
parts.pop()
return parts

if len(self.url) > 1:
segments_url = segments(self.url)
segments_request = segments(request.path)
matching_segments = \
segments_request[0:len(segments_url)] == segments_url
else:
matching_segments = False
matching_completpath = request.path == self.url
return matching_endpoint or matching_subpath or matching_completpath
return matching_endpoint or matching_segments or matching_completpath

def register(self, endpoint=None, text=None, order=0, external_url=None,
endpoint_arguments_constructor=None,
Expand Down
18 changes: 18 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# This file is part of Flask-Menu
# Copyright (C) 2013, 2014, 2015 CERN.
# Copyright (C) 2017 Marlin Forbes
#
# Flask-Menu is free software; you can redistribute it and/or modify
# it under the terms of the Revised BSD License; see LICENSE file for
Expand Down Expand Up @@ -785,3 +786,20 @@ def two_three_five():
visible_should
)
)

def test_active_checks_segment_not_prefix(self):
Menu(self.app)

@register_menu(self.app, 'object', 'Object')
@self.app.route('/object')
def object():
return 'object'

@register_menu(self.app, 'objects', 'Objects')
@self.app.route('/objects')
def objects():
return 'objects'

with self.app.test_client() as c:
c.get('/objects')
assert current_menu.submenu('object').active is not True

0 comments on commit 966a7c2

Please sign in to comment.