Overview ======== Let's assume we have this URL path:: /news/2010/oct/hello-world/ We need to convert it to :term:`breadcrumbs` and display along the heading this way:: News → 2010 news → October 2010 So we just type this in our template:: {% get_breadcrumb_trail as trail %}

{% breadcrumb %}

...and this is the result::

Hello world

How does this work? ------------------- Current URL path is split into hierarchical parts:: * /news/ * /news/2010/ * /news/2010/oct/ * /news/2010/oct/hello-world/ For each part a :class:`navigation.helpers.Crumb` instance is created. It stores the URL and the corresponding title. But how do we know the title? The URL title is resolved by a :term:`crumb resolver`. By default two resolvers are available: `_resolve_flatpage` and `_resolve_by_callback`. The first one looks for a `FlatPage` object with given URL path in the database (if `django.contrib.flatpages` is activated in settings). If this resolver failed (i.e. flatpages are not available or there's no `FlatPage` with such URL path), then next crumb resolver is called. The crumb resolver `_resolve_by_callback` peeks into the URL maps and attempts to resolve the URL into a view function. If such function is found, the resolver looks whether the function has the "breadcrumb" attribute. This attribute can be set by wrapping the view in decorator :func:`navigation.decorators.breadcrumb`:: from navigation.decorators import breadcrumb @breadcrumb('Hello') def say_hello(request): ... @breadcrumb(lambda request: u'%s settings' % request.user) def user_settings(request): ... If the attribute is not found, we can't guess the name and give up. A dummy breadcrumb is add to the trail. However, we could also try "humanizing" the function's ``__name__`` attribute or use a custom path-to-name mapping. You can do that easily by creating your own crumb resolvers and registering them this way:: from navigation.resolvers import crumb_resolver @crumb_resolver def my_custom_resolver_function(request, url): return Crumb(url, 'Hello!') .. topic:: TODO I'll probably make this more explicit, e.g. add a settings variable like this:: NAVIGATION_RESOLVERS = [ 'navigation.resolvers.resolve_flatpage', 'navigation.resolvers.resolve_by_callback', 'utils.navigation.my_custom_resolver_function', ]