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 = ['
']
for item in self.items:
fragments.append('- ')
fragments.append(str(item))
fragments.append('
')
fragments.append('
')
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()