class Menu: """A class for generating a renderable menu that modifies URL parameters.""" def __init__(self, request, key, items, default=None, exclude=['page']): """Constructs a new Menu. request: the request object for the current view. key: the name of the URL parameter for this Menu. items: a sequence of MenuItems. default: the key of the MenuItem to be selected by default. exclude: a list of URL parameters to remove when constructing the links for each MenuItem. """ self.key = key self.items = items value = request.GET.get(self.key, default) self.selected = value for item in self.items: item.selected = (value == item.key) copy = request.GET.copy() copy[self.key] = item.key for key2 in exclude: if key2 in copy: del copy[key2] item.link = u'%s?%s' % (request.path, copy.urlencode()) def as_list(self): """Renders the Menu as an unordered list.""" fragments = ['') return ''.join(fragments) def __str__(self): """Renders the Menu using the default method.""" return self.as_list() class MenuItem: """A class representing an item in a Menu.""" def __init__(self, key, label): """Constructs a MenuItem. key: the value of the Menu URL parameter when this item is selected. label: the name of the menu item as it will appear on the page. """ self.key = key self.label = label def __str__(self): """Renders the MenuItem. The item appears as a link only if not selected. """ if self.selected: return u'%s' % (self.label) else: return u'%s' % (self.link, self.label) def sample(): """Returns a rendered sample menu. >>> sample() '' """ from django.http import HttpRequest, QueryDict items = [MenuItem('hot', "Hot!"), MenuItem('new', "New!"), ] request = HttpRequest() request.path = '/home/' request.GET = QueryDict("topic=hot&search=blah&page=3") menu = Menu(request, 'topic', items) return menu.as_list()