Navigation in django

后端 未结 30 1242

I\'ve just done my first little webapp in django and I love it. I\'m about to start on converting an old production PHP site into django and as part its template, there is a

相关标签:
30条回答
  • 2020-11-27 09:46

    A little enhancement over @tback's answer, without any %if% tags:

    # navigation.py
    from django import template
    from django.core.urlresolvers import resolve
    
    register = template.Library()
    
    @register.filter(name="activate_if_active", is_safe=True)
    def activate_if_active(request, urlname):
      if resolve(request.get_full_path()).url_name == urlname:
        return "active"
      return ''
    

    Use it in your template like that:

    {% load navigation %}
    <li class="{{ request|activate_if_active:'url_name' }}">
      <a href="{% url 'url_name' %}">My View</a>
    </li>
    

    And include "django.core.context_processors.request" in your TEMPLATE_CONTEXT_PROCESSORS setting.

    0 讨论(0)
  • 2020-11-27 09:46

    Mine is a bit similar to another JS approach submitted previously.. just without jQuery...

    Say we have in base.html the following:

    <div class="pure-u-1 pure-menu pure-menu-open pure-menu-horizontal header" >
        <ul class="">
            <li id="home"><a href="{% url 'article:index' %}">Home</a></li>
            <li id="news"><a href="{% url 'article:index' %}">News</a></li>
            <li id="analysis"><a href="{% url 'article:index' %}">Analysis</a></li>
            <li id="opinion"><a href="{% url 'article:index' %}">Opinion</a></li>
            <li id="data"><a href="{% url 'article:index' %}">Data</a></li>
            <li id="events"><a href="{% url 'article:index' %}">Events</a></li>
            <li id="forum"><a href="{% url 'article:index' %}">Forum</a></li>
            <li id="subscribe"><a href="{% url 'article:index' %}">Subscribe</a></li>
        </ul>
        <script type="text/javascript">
            (function(){
                loc=/\w+/.exec(window.location.pathname)[0];
                el=document.getElementById(loc).className='pure-menu-selected';         
            })();   
        </script>
    </div>
    

    I just made my hierarchy to follow a certain URL pattern... after the host address... i have my main category, eg, home, news, analysis, etc. and the regex just pulls the first word out of the location

    0 讨论(0)
  • 2020-11-27 09:47

    Just another ehnancement of the original solution.

    This accept multiple patterns and which is best also unnamed patterns written as relative URL wrapped in '"', like following:

    {% url admin:clients_client_changelist as clients %}
    {% url admin:clients_town_changelist as towns %}
    {% url admin:clients_district_changelist as districts %}
    
    <li class="{% active "/" %}"><a href="/">Home</a></li>
    <li class="{% active clients %}"><a href="{{ clients }}">Clients</a></li>
    {% if request.user.is_superuser %}
    <li class="{% active towns districts %}">
        <a href="#">Settings</a>
        <ul>
            <li><a href="{{ towns }}">Towns</a></li>
            <li><a href="{{ districts }}">Districts</a></li>
        </ul>
    </li>
    {% endif %}
    

    Tag goes like this:

    from django import template
    
    register = template.Library()
    
    @register.tag
    def active(parser, token):
        args = token.split_contents()
        template_tag = args[0]
        if len(args) < 2:
            raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
        return NavSelectedNode(args[1:])
    
    class NavSelectedNode(template.Node):
        def __init__(self, urls):
            self.urls = urls
    
        def render(self, context):
            path = context['request'].path
    
            for url in self.urls:
                if '"' not in url:
                    cpath = template.Variable(url).resolve(context)
                else:
                    cpath = url.strip('"')
    
                if (cpath == '/' or cpath == '') and not (path == '/' or path == ''):
                    return ""
                if path.startswith(cpath):
                    return 'active'
            return ""
    
    0 讨论(0)
  • 2020-11-27 09:49

    I took the code from nivhab above and removed some wierdness and made it into a clean templatetag, modified it so that /account/edit/ will still make /account/ tab active.

    #current_nav.py
    from django import template
    
    register = template.Library()
    
    @register.tag
    def current_nav(parser, token):
        import re
        args = token.split_contents()
        template_tag = args[0]
        if len(args) < 2:
            raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
        return NavSelectedNode(args[1])
    
    class NavSelectedNode(template.Node):
        def __init__(self, url):
            self.url = url
    
        def render(self, context):
            path = context['request'].path
            pValue = template.Variable(self.url).resolve(context)
            if (pValue == '/' or pValue == '') and not (path  == '/' or path == ''):
                return ""
            if path.startswith(pValue):
                return ' class="current"'
            return ""
    
    
    
    #template.html
    {% block nav %}
    {% load current_nav %}
    {% url home as home_url %}
    {% url signup as signup_url %}
    {% url auth_login as auth_login_url %}
    <ul class="container">
        <li><a href="{{ home_url }}"{% current_nav home_url %} title="Home">Home</a></li>
        <li><a href="{{ auth_login_url }}"{% current_nav auth_login_url %} title="Login">Login</a></li>
        <li><a href="{{ signup_url }}"{% current_nav signup_url %} title="Signup">Signup</a></li>
    </ul>
    {% endblock %}
    
    0 讨论(0)
  • 2020-11-27 09:49

    Here's my go at it. I ended up implementing a class in my views that contains my navigation structure (flat with some metadata). I then inject this to the template and render it out.

    My solution deals with i18n. It probably should be abstracted out a bit more but I haven't really bothered with that really.

    views.py:

    from django.utils.translation import get_language, ugettext as _
    
    
    class Navi(list):
        items = (_('Events'), _('Users'), )
    
        def __init__(self, cur_path):
            lang = get_language()
            first_part = '/' + cur_path.lstrip('/').split('/')[0]
    
            def set_status(n):
                if n['url'] == first_part:
                    n['status'] == 'active'
    
            for i in self.items:
                o = {'name': i, 'url': '/' + slugify(i)}
                set_status(o)
                self.append(o)
    
    # remember to attach Navi() to your template context!
    # ie. 'navi': Navi(request.path)
    

    I defined the template logic using includes like this. Base template:

    {% include "includes/navigation.html" with items=navi %}
    

    Actual include (includes/navigation.html):

     <ul class="nav">
         {% for item in items %}
             <li class="{{ item.status }}">
                 <a href="{{ item.url }}">{{ item.name }}</a>
             </li>
         {% endfor %}
     </ul>
    

    Hopefully someone will find this useful! I guess it would be pretty easy to extend that idea to support nested hierarchies etc.

    0 讨论(0)
  • 2020-11-27 09:54

    Create an include template "intranet/nav_item.html":

    {% load url from future %}
    
    {% url view as view_url %}
    <li class="nav-item{% ifequal view_url request.path %} current{% endifequal %}">
        <a href="{{ view_url }}">{{ title }}</a>
    </li>
    

    And include it in the nav element:

    <ul>
        {% include "intranet/nav_item.html" with view='intranet.views.home' title='Home' %}
        {% include "intranet/nav_item.html" with view='crm.views.clients' title='Clients' %}
    </ul>
    

    And you need to add this to settings:

    from django.conf import global_settings
    TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
        'django.core.context_processors.request',
    )
    
    0 讨论(0)
提交回复
热议问题