Django dynamically get view url and check if its the current page

Question:

Consider this basic menu:

<ul class="nav navbar-nav">
  <li class="active"><a href="{% url 'home' %}">Home</a></li>
  <li><a href="{% url 'about' %}">About</a></li>
</ul>

I’m trying to give the current page’s link an active class, and I want to do this dynamically based on current url and the view’s url. So that when a user visits the about page, that page now has the active class and the homepage does not.

I’d like to logic to work like this inside of the <li></li> tags:

{% if request.get_full_path = "{% url 'home' %}" %}class="active"{% endif %}
{% if request.get_full_path = "{% url 'about' %}" %}class="active"{% endif %}

but clearly I cant have two {% ... %} nested inside of each other.

Any ideas on how to get around nesting the two?

Asked By: agconti

||

Answers:

I usually use template inheritance in my navigation, in a similar way to the answer alecxe linked to. However, it is possible to compare the use the current URL in an if tag, as you are trying to do.

The url tag allows you to save the result to a variable. You can then use that variable in your if tag.

{% url 'home' as home_url %}
<a href="{{ home_url }}" {% if request.get_full_path == home_url %}class="active"{% endif %}>Home</a>
Answered By: Alasdair

Very old thread! My answer might help future readers.
I did that this way (just compare request URL name with your pathname)

<a class="nav-link {% if request.resolver_match.url_name == 'index' %}active{% endif %}" href="#">Home</a>
Answered By: hassanrazadev

if your app has a namespace (let say blog) then:

<li class="nav-item">
  <a
    class="nav-link{% if request.resolver_match.namespace == 'blog' and request.resolver_match.url_name == 'post_list' %} active{% endif %}" 
    href="{% url 'blog:post_list' %}">
    Blog
  </a>
</li>

remember to define app_name in blog/urls.py:

app_name = 'blog'
urlpatterns = [
    path('', views.post_list, name='post_list'),
    # ...
]
Answered By: cizario

The templatetags are very useful for this kind of need. Moreover, the templatetag can access the context and the request. Use the following as an idea to tailor up based on your needs.

# yourapp/templatetags/utils.py

from django import template
from django.urls import reverse

register = template.Library()


@register.simple_tag(takes_context=True)
def get_active_class(context, url_to_check: str) -> str:
    request = context['request']
    if request.get_full_path() == reverse(url_to_check):
        # this could be in the settings or in the app config
        return "is-active"
    return ""

In your sidebar you can now create a link easily

# your sidebar.html somewhere in your code

{% load utils %}

 <ul class="menu-list">
    <li>
      <a 
         href="{% url 'home' %}"
         class="{% get_active_class 'home' %}">Home
     </a>
    </li>

    <li>
      <a 
         href="{% url 'settings' %}"
         class="{% get_active_class 'settings' %}">Home
     </a>
    </li>
 </ul>
Answered By: Karim N Gorjux
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.