How to implement breadcrumbs in a Django template?

前端 未结 12 2066
無奈伤痛
無奈伤痛 2020-12-07 09:45

Some solutions provided on doing a Google search for \"Django breadcrumbs\" include using templates and block.super, basically just extending the base blocks and adding the

12条回答
  •  执念已碎
    2020-12-07 10:25

    Note: I provide the full snippet below, since djangosnippets has been finicky lately.

    Cool, someone actually found my snippet :-) The use of my template tag is rather simple.

    To answer your question there is no "built-in" django mechanism for dealing with breadcrumbs, but it does provide us with the next best thing: custom template tags.

    Imagine you want to have breadcrumbs like so:

    Services -> Programming
    Services -> Consulting
    

    Then you will probably have a few named urls: "services", and "programming", "consulting":

        (r'^services/$',
         'core.views.services',
         {},
         'services'),
    
        (r'^services/programming$',
         'core.views.programming',
         {},
         'programming'),
    
        (r'^services/consulting$',
         'core.views.consulting',
         {},
         'consulting'),
    

    Now inside your html template (lets just look at consulting page) all you have to put is:

    //consulting.html
    {% load breadcrumbs %}
    
    {% block breadcrumbs %}
    {% breadcrumb_url 'Services' services %}
    {% breadcrumb_url 'Consulting' consulting %}
    
    {% endblock %}
    

    If you want to use some kind of custom text within the breadcrumb, and don't want to link it, you can use breadcrumb tag instead.

    //consulting.html
    {% load breadcrumbs %}
    
    {% block breadcrumbs %}
      {% breadcrumb_url 'Services' services %}
      {% breadcrumb_url 'Consulting' consulting %}
      {% breadcrumb 'We are great!' %}  
    {% endblock %}
    

    There are more involved situations where you might want to include an id of a particular object, which is also easy to do. This is an example that is more realistic:

    {% load breadcrumbs %}
    
    {% block breadcrumbs %}
    {% breadcrumb_url 'Employees' employee_list %}
    {% if employee.id %}
        {% breadcrumb_url employee.company.name company_detail employee.company.id %}
        {% breadcrumb_url employee.full_name employee_detail employee.id %}
        {% breadcrumb 'Edit Employee ' %}
    {% else %}
        {% breadcrumb 'New Employee' %}
    {% endif %}
    
    {% endblock %}
    

    DaGood breadcrumbs snippet

    Provides two template tags to use in your HTML templates: breadcrumb and breadcrumb_url. The first allows creating of simple url, with the text portion and url portion. Or only unlinked text (as the last item in breadcrumb trail for example). The second, can actually take the named url with arguments! Additionally it takes a title as the first argument.

    This is a templatetag file that should go into your /templatetags directory.

    Just change the path of the image in the method create_crumb and you are good to go!

    Don't forget to {% load breadcrumbs %} at the top of your html template!

    from django import template
    from django.template import loader, Node, Variable
    from django.utils.encoding import smart_str, smart_unicode
    from django.template.defaulttags import url
    from django.template import VariableDoesNotExist
    
    register = template.Library()
    
    @register.tag
    def breadcrumb(parser, token):
        """
        Renders the breadcrumb.
        Examples:
            {% breadcrumb "Title of breadcrumb" url_var %}
            {% breadcrumb context_var  url_var %}
            {% breadcrumb "Just the title" %}
            {% breadcrumb just_context_var %}
    
        Parameters:
        -First parameter is the title of the crumb,
        -Second (optional) parameter is the url variable to link to, produced by url tag, i.e.:
            {% url person_detail object.id as person_url %}
            then:
            {% breadcrumb person.name person_url %}
    
        @author Andriy Drozdyuk
        """
        return BreadcrumbNode(token.split_contents()[1:])
    
    
    @register.tag
    def breadcrumb_url(parser, token):
        """
        Same as breadcrumb
        but instead of url context variable takes in all the
        arguments URL tag takes.
            {% breadcrumb "Title of breadcrumb" person_detail person.id %}
            {% breadcrumb person.name person_detail person.id %}
        """
    
        bits = token.split_contents()
        if len(bits)==2:
            return breadcrumb(parser, token)
    
        # Extract our extra title parameter
        title = bits.pop(1)
        token.contents = ' '.join(bits)
    
        url_node = url(parser, token)
    
        return UrlBreadcrumbNode(title, url_node)
    
    
    class BreadcrumbNode(Node):
        def __init__(self, vars):
            """
            First var is title, second var is url context variable
            """
            self.vars = map(Variable,vars)
    
        def render(self, context):
            title = self.vars[0].var
    
            if title.find("'")==-1 and title.find('"')==-1:
                try:
                    val = self.vars[0]
                    title = val.resolve(context)
                except:
                    title = ''
    
            else:
                title=title.strip("'").strip('"')
                title=smart_unicode(title)
    
            url = None
    
            if len(self.vars)>1:
                val = self.vars[1]
                try:
                    url = val.resolve(context)
                except VariableDoesNotExist:
                    print 'URL does not exist', val
                    url = None
    
            return create_crumb(title, url)
    
    
    class UrlBreadcrumbNode(Node):
        def __init__(self, title, url_node):
            self.title = Variable(title)
            self.url_node = url_node
    
        def render(self, context):
            title = self.title.var
    
            if title.find("'")==-1 and title.find('"')==-1:
                try:
                    val = self.title
                    title = val.resolve(context)
                except:
                    title = ''
            else:
                title=title.strip("'").strip('"')
                title=smart_unicode(title)
    
            url = self.url_node.render(context)
            return create_crumb(title, url)
    
    
    def create_crumb(title, url=None):
        """
        Helper function
        """
        crumb = """""" \
                """Arrow""" \
                """"""
        if url:
            crumb = "%s%s" % (crumb, url, title)
        else:
            crumb = "%s  %s" % (crumb, title)
    
        return crumb
    

提交回复
热议问题