Login

Multi-level (tree-ish) navigation

Author:
jpic
Posted:
September 28, 2008
Language:
Python
Version:
1.4
Score:
0 (after 2 ratings)

An old snippet I made in my first django project. Nowadays I code menus in HTML and just use the perms proxy: https://docs.djangoproject.com/en/1.0/topics/auth/#id6

Credits, (awsome persons that helped me getting it to work efficiently and for free):

  • Yhg1s and waveform from #python@freenode
  • zendak from #django@freenode

Thank you!

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# 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 += '<ul>'
        for menuitem in self:
            html += menuitem.render()
        if ul:
            html+= '</ul>'
        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 = '<a href="' + self.url + '" title="' + self.title + '">' + self.title + '</a>'
        return html

    def render(self):
        inside = self.render_inside()
        if len(self) == 0:
            html = '<li>' + inside + '</li>'
        else:
            html = '<li>' + inside + '<ul>'
            for menuitem in self:
                html += menuitem.render()
            html+= '</ul></li>'
        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)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

jpic (on March 15, 2009):

Update:

  • Refactored Menu by inheriting from builtin list.
  • Added a factory.

#

Please login first before commenting.