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
|
from common.models import Menu, MenuItem
from django import template
from django.core.cache import cache
register = template.Library()
def build_menu(parser, token):
"""
{% menu menu_name %}
"""
try:
tag_name, menu_name = token.split_contents()
except:
raise template.TemplateSyntaxError, "%r tag requires exactly one argument" % token.contents.split()[0]
return MenuObject(menu_name)
class MenuObject(template.Node):
def __init__(self, menu_name):
self.menu_name = menu_name
def render(self, context):
if 'request' not in context:
return ''
real_menu_name = context.get(self.menu_name, self.menu_name)
current_path = context['request'].path
user = context['request'].user
context['menuitems'] = get_items(real_menu_name, current_path, user)
return ''
def build_sub_menu(parser, token):
"""
{% submenu %}
"""
return SubMenuObject()
class SubMenuObject(template.Node):
def __init__(self):
pass
def render(self, context):
current_path = context['request'].path
user = context['request'].user
menu = False
for m in Menu.objects.filter(base_url__isnull=False):
if m.base_url and current_path.startswith(m.base_url):
menu = m
if menu:
context['submenu_items'] = get_items(menu.slug, current_path, user)
context['submenu'] = menu
else:
context['submenu_items'] = context['submenu'] = None
return ''
def get_items(menu_name, current_path, user):
"""
If possible, use a cached list of items to avoid continually re-querying
the database.
The key contains the menu name, whether the user is authenticated, and the current path.
Disable caching by setting MENU_CACHE_TIME to -1.
"""
from django.conf import settings
cache_time = getattr(settings, 'MENU_CACHE_TIME', 1800)
debug = getattr(settings, 'DEBUG', False)
if cache_time >= 0 and not debug:
cache_key = 'django-menu-items/%s/%s/%s' % (menu_name, current_path, user.is_authenticated())
menuitems = cache.get(cache_key, [])
if menuitems:
return menuitems
else:
menuitems = []
try:
menu = Menu.objects.get(slug=menu_name)
except Menu.DoesNotExist:
return []
for i in MenuItem.objects.filter(menu=menu).order_by('order'):
current = ( i.link_url != '/' and current_path.startswith(i.link_url)) or ( i.link_url == '/' and current_path == '/' )
if menu.base_url and i.link_url == menu.base_url and current_path != i.link_url:
current = False
show_anonymous = i.anonymous_only and user.is_anonymous()
show_auth = i.login_required and user.is_authenticated()
if (not (i.login_required or i.anonymous_only)) or (i.login_required and show_auth) or (i.anonymous_only and show_anonymous):
menuitems.append({'url': i.link_url, 'title': i.title, 'current': current,})
if cache_time >= 0 and not debug:
cache.set(cache_key, menuitems, cache_time)
return menuitems
register.tag('menu', build_menu)
register.tag('submenu', build_sub_menu)
|