With this script you can create a simple breadcrumbs line for navigation: Home >> Page >> Subpage ...
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 | # -*- coding: iso-8859-1 -*-
# $Id: breadcrumbs.py 122 2008-10-01 10:31:57Z tguettler $
# $HeadURL: svn+ssh://svnserver/svn/djangotools/trunk/utils/breadcrumbs.py $
# http://www.djangosnippets.org/snippets/1026/
# Python
from urlparse import urljoin
# Django
from django import http
from django.core import urlresolvers
from django.core.urlresolvers import reverse
from django.conf import settings
from django.utils.http import urlquote
from django.utils.html import conditional_escape as escape
from django.utils.safestring import mark_safe
def join(str, mylist):
str=escape(str)
return mark_safe(str.join([escape(item) for item in mylist]))
'''
Simple Breadcrumbs for Django:
The value of request.path gets examined and all views of the 'upper' urls
need to have an attribute'breadcrumbs'. The attribute can be a
string or a method. If it is a method it needs to accept two arguments
(args and kwargs) which correspond to the arguments of the view.
Example: request.path == '/users/foo/config/'
Views:
def config(request, ...):
...
config.breadcrumbs=u'Config'
def user(request, username):
...
user.breadcrumbs=lambda args, kwargs: args[1]
def users(request):
...
users.breadcrumbs='Users'
The URL
/users/foo/config/
will get to these breadcrumbs:
Users>>foo>>Config
All except the last breadcrumb will be links.
Implemented with Django's resolve(url)
Usage:
breadcrumbs, default_title = breadcrumbs.get_breadcrumbs(request)
breadcrumbs: SafeUnicode HTML String
default_title: Unicode String with the name of the current view.
Let Hansel and Grethel find their way home:
http://en.wikipedia.org/wiki/Hansel_and_Gretel
'''
def link_callback_default(url, bc):
return mark_safe(u'<a href="%s">%s</a>' % (
urlquote(url), escape(bc)))
def join_callback_default(breadcrumbs):
return mark_safe(u'<div class="breadcrumbs">%s</div>' % (join('>>', breadcrumbs)))
def get_breadcrumbs(request, link_callback=None, join_callback=None):
if link_callback is None:
link_callback=link_callback_default
if join_callback is None:
join_callback=join_callback_default
path_info=request.META['PATH_INFO']
url=path_info
breadcrumbs=[]
resolver = urlresolvers.get_resolver(None)
count=0
while True:
count+=1
assert count<1000, count
callback=None
try:
callback, callback_args, callback_kwargs = resolver.resolve(url)
except http.Http404, exc:
pass
else:
bc=getattr(callback, 'breadcrumbs', None)
assert bc!=None, u'Callback %s.%s function breadcrumbs does not exist.' % (
callback.__module__, callback.__name__)
sub_crumbs=[]
if isinstance(bc, basestring):
pass
elif hasattr(bc, '__call__'):
bc=bc(callback_args, callback_kwargs)
if isinstance(bc, tuple):
# The callable can return a tuple. The first entry is
# the name, the second is a tuple list of (url, name)
# Example .../objects/123/ (Object 123 is part of Object 99):
# Objects>>99>>123
bc, sub_crumbs = bc
else:
raise Exception('Unkown type for breadcrumbs attribute: %s %s %r' % (
type(bc), bc, bc))
if url!=path_info:
bc=link_callback('%s%s' % (request.META['SCRIPT_NAME'], url), bc)
breadcrumbs.append(bc)
for bc_url, name in sub_crumbs:
breadcrumbs.append(link_callback(bc_url, name))
# Parent URL heraussuchen.
if url=='/':
break
url=urljoin(url, '..')
assert breadcrumbs
default_title=breadcrumbs[0]
breadcrumbs.append('')
breadcrumbs.reverse()
joined=join_callback(breadcrumbs)
return (joined, default_title)
def test_all_views():
u'''
Unittest: Check if all you views have a breadcrumbs()
attribute.
Django views are ignored.
'''
resolver=urlresolvers.get_resolver(None)
missing=[]
for function, patterns in resolver.reverse_dict.items():
if not function:
continue
sub_resolver=patterns[0]
if isinstance(function, basestring): # TODO: Alias auflösen.
continue
if function.__module__.startswith('django.'):
continue
name='%s.%s' % (function.__module__, function.__name__)
if not hasattr(function, 'breadcrumbs'):
missing.append(name)
continue
bc=function.breadcrumbs
if isinstance(bc, basestring):
try:
unicode(bc)
except UnicodeError, exc:
missing.append('UnicodeError, %s: %s' % (name, exc))
missing.sort()
assert not missing, 'Missing breadcrumbs function: %s' % (missing)
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 3 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
I really like this snippet, and customized it to have my own breadcrumb style (a list rather than the >>> method - better for accessibility).
A more serious problem, but easily rectified, is that it throws an assertion error whenever I access a Django builtin view (such as when I log in). In your test function, you wisely omitted checking the Django views. However, your main function doesn't check.
One whould just write wrapper views to get around this problem - as it'll ensure a breadcrumb still appears on those pages. But that would be a poor idea if one were to use the Django admin. So I had to put in a test for internal Django views in the main code (just a single line and lots of indenting).
#
I use breadcrumbs only for user visibles pages. I don't use it for the admin page.
#
Hi, Im just starting to use django.
I didnt get where to exactly put the code for the usage:
Usage: breadcrumbs, default_title = breadcrumbs.get_breadcrumbs(request) breadcrumbs: SafeUnicode HTML String default_title: Unicode String with the name of the current view.
Also, what do you have to put on the template?
Thanks in advance!
#
Please login first before commenting.