Highlight current menu item in sidebar

Viewed 13851

I'm using django with Twitter Bootstrap. My current view resembles one of the examples provided. Looking at the example, one can imagine the user clicking one of the links in the sidebar to see different views, each framed with this same sidebar. One would imagine that the link selected would then be highlighted just like the example using the code:

<li class="active"><a href="/sample/link/here/">Link</a></li>

The active class needs to be attached to the correct menu item. How might I assign this "active" class to the correct menu item? Originally, I tried using a variable from my view to assign it with jquery:

$(document).ready(function() {
    $("#{{ current_view }}_nav").addClass('active');
});

<li id="linkone_nav"><a href="/sample/link/here/">Link</a></li>

This seems cumbersome though. It requires that I pass the id to the template from the view. Lots of ids to manage as well. Is there a better / more preferred way to assign this active class?

7 Answers

You might consider the following approach to resolve the issue in Django.

It works fine without using javascript. Just by using the pure Django you should be able to address the most of the situations where you need to highlight menu options.

In this example I am using Bootstrap 4 but it is not important. You can use your own CSS and you will be ok. The idea here is just to show the use of request.resolver_match.url_name as url_name to achieve what you need.

{% with request.resolver_match.url_name as url_name %}
   <ul class="navbar-nav mr-auto">
      <li class="{% if url_name == 'your url' %}nav-item active{% else %}nav-item{% endif %}">
       <a class="nav-link" href="{% url 'your url 1' %}">Menu option 1</a>
      </li>
      <li class="{% if url_name == 'your url' %}nav-item active{% else %}nav-item{% endif %}">
       <a class="nav-link" href="{% url 'your url 2' %}">Menu option 2</a>
      </li>
   </ul>
{% endwith %}

I used a a simple_tag for that purpose. Maybe someone will find it helpful.

Make a file isactive.py and put in your templatetags directory on the level of your app template path.

from django import template
from django import urls
register = template.Library()

@register.simple_tag
def isactive(page_name, request_url):
    rev_url = ''
    try:     
        rev_url = urls.reverse(page_name)
    except:
        return ''
    if (rev_url == request_url):
            return 'active'
    return ''

And in your html template

{% load isactive %}

after loading static and in your menu

<a href="{% url 'my_table_list' %}" class="nav-link {% isactive 'my_table_list' request.path %}">

When rendering - django is executing function isactive where 1st parameter is the name of the page and the other is the path. Inside the isactive function the name is resolved and compared. When it matches the active string is returned and placed in resulting html. You have to put that call in every nav link.

The name of the page is taken from urlpatterns in urls.py of your app

urlpatterns = (
    ...
    path("my_table/list/", views.mytableListView.as_view(), name="my_table_list"),
    ....
Related