# Works flawlessly with http://www.dynamicdrive.com/style/csslibrary/item/jquery_multi_level_css_menu_horizontal_blue/ class Menu(list): def render(self, ul=True): html = '' if ul: html += '' return html def add( self, title, url=None ): item = MenuItem( title, url ) self.append( item ) return item class MenuItem(Menu): def __init__(self, title, url = None): super(MenuItem, self).__init__() self.title = title if not url: self.url = '' else: self.url = url def render_inside(self): html = '' + self.title + '' return html def render(self): inside = self.render_inside() if len(self) == 0: html = '
  • ' + inside + '
  • ' else: html = '
  • ' + inside + '
  • ' return html def append_to_menus( self, menus ): for menu in menus: menu.append( self ) return self class MenuFactories(object): def __init__(self, source, menu=None): self.source = source if not menu: menu = Menu() self.menu = menu if isinstance(source, dict): self.parse_dict(self.source, self.menu) def parse_dict(self, source, menu): for k, v in source.items(): if isinstance(v, dict): self.parse_dict( v, menu.add(k ) ) else: menu.add( k, v ) return menu # Example context processor: def nav( request ): nav = {} immo = "Immobilier" user = "Utilisateur" admin = "Administration" menu = Menu() immo = menu.add( immo ) user = menu.add( user ) acheter = immo.add( "Acheter" ) investissement = acheter.add( "Investissement locatif" ) accession = acheter.add( "Accession" ) louer = immo.add( "Louer" ) menus = investissement, accession, louer MenuItem( "Chambres", "/cherche/chambres/accession/profil" ).append_to_menus( menus ) MenuItem( "Appartements", "/cherche/appartements/accession/profil" ).append_to_menus( menus ) MenuItem( "Villas, Maisons, Pavillons ...", "/cherche/villas-maisons-pavillons/accession/profil" ).append_to_menus( menus ) MenuItem( "Masionn de ville, village ...", "/cherche/maisons-de-ville-village/accession/profil" ).append_to_menus( menus ) MenuItem( "Maisons de caractère", "/cherche/maisons-de-caractère/accession/profil" ).append_to_menus( menus ) MenuItem( "Parking, garages ...", "/cherche/parkings-garages/accession/profil" ).append_to_menus( menus ) MenuItem( "Programmes neufs" ).append_to_menus( menus ) if request.user.is_staff: admin = menu.add( "Administration" ) admin.add( "Rechercher des utilisateurs", "/profiles/" ) admin.add( "Interface Complête", "/admin" ) if request.user.is_authenticated(): # if "Partenaires" in request.user.groups.all() user.add( "Mes dernières recherches", "/mesrecherches/" ) user.add( "Mes coordonnées", "/profiles/edit" ) user.add( "Déconnection", "/accounts/logout" ) else: user.add( "Recevoir un nouveau mot de passe", "/accounts/password/reset/" ) user.add( "Enregistrement d'un nouveau compte", "/accounts/register/" ) user.add( "Authentification", "/accounts/login" ) # in the template, use {{ nav|safe }} return { 'nav': menu.render() } # Example using the factory: def nav( request ): menu = menus.Menu() if request.user.is_staff: nav = { "Portefeuille": { "Saisie d'une nouvelle location": '/admin/immo/location/add/', "Saisie d'un nouveau LCP (Immo d'entreprise)": '/admin/immo/lcp/add', "Saisie d'un nouveau terrain": '/admin/immo/terrain/add/', "Saisie d'un nouveau lot": '/admin/immo/lot/add/', "Statistique visite lot": '/statistiques/', "Rapprochement lot/contact": '/admin/immo/rapprochement/add/', "Rapprochement contact/lot": '/admin/immo/rapprochement/add/', }, "Contact": { "Saisie d'un nouveau contact": '/admin/auth/user/add/', "Liste des contacts": '/admin/auth/user/', "Liste des demandes": '/admin/immo/demande/', }, "Evenement": { "Saisie d'un evenement": '/admin/crm/evenement/add/', "Liste des evenements": '/admin/crm/evenement/' }, "Reservation": { "Saisie de reservation de location": '/admin/resa/location/add/', "Liste des reservations de location": '/admin/resa/location/', "Saise de compromis de vente": '/admin/resa/vente/add/', "Liste des compromis de ventes": '/admin/resa/vente/', }, "Administration": { "Analyse du portefeuille": { "LCP (Immo d'entreprise)": '/admin/immo/lcp/', "Terrain": '/admin/immo/terrain/', "Lot": '/admin/immo/lot/', }, "Analyse des activités des négociateur": '/?/', "Synthèse des rémunérations": '/?/', "Gestion des utilisateurs": '/admin/auth/user/', "Documents agence": '/admin/immo/document/', "Paramétrage du logiciel": '/admin/', "Paramétrage site Agence": '/admin/flatpages/flatpage/', }, } f = menus.MenuFactories(nav, menu)