Skip to content

Active link in django

we'll explore different techniques to add an 'active' class to navigation elements based on the user's location, providing visual cues that enhance navigation clarity.

Method 1: URL Comparison with Template Tags

method 1

The first method involves straightforward URL comparison using Django's template tags. By comparing the request's path with the URLs associated with each navigation item, we can dynamically add the active class.

<ul class="nav">
    <li class="{% if request.path == '/' %}active{% endif %}">
        <a href="/">Home</a>
    </li>
    <li class="{% if request.path == '/about/' %}active{% endif %}">
        <a href="/about/">About</a>
    </li>
    <!-- Add more navigation items here -->
</ul>

Method 2: Assigning URL to Variables

method 2

A more organized approach involves assigning URLs to variables using Django's {% url %} tag. This allows for cleaner template code and easier maintenance.

{% url 'home' as home_url %}
{% url 'about' as about_url %}

<ul class="nav">
    <li class="{% if request.path == home_url %}active{% endif %}">
        <a href="{% url 'home' %}">Home</a>
    </li>
    <li class="{% if request.path == about_url %}active{% endif %}">
        <a href="{% url 'about' %}">About</a>
    </li>
    <!-- Add more navigation items here -->
</ul>

Method 3: URL Prefix Comparison

method 3

For situations where multiple URLs share a common prefix, such as subpages, the startswith template filter can be utilized to simplify the code.

{% url 'home' as home_url %}
{% url 'about' as about_url %}

<ul class="nav">
    <li class="{% if request.path == home_url or request.path.startswith('/home/') %}active{% endif %}">
        <a href="{% url 'home' %}">Home</a>
    </li>
    <li class="{% if request.path == about_url %}active{% endif %}">
        <a href="{% url 'about' %}">About</a>
    </li>
    <!-- Add more navigation items here -->
</ul>

Conclusion

Enhancing navigation with an active state in Django not only improves user experience but also adds a touch of professionalism to your website. By implementing one of these methods, you can guide users seamlessly through your site, ensuring they always know where they are. Choose the approach that best fits your project's requirements and coding style, and elevate your Django website's navigation to new heights.


Django Template Patterns

active link

Pattern a the active link

Problem: The navigation bar is a common component in most pages. However, the active link needs to reflect the current page the user is on.

Solution: Conditionally, change the active link markup by setting context variables or based on the request path.

Problem details

The naive way to implement the active link in a navigation bar is to manually set it in every page. However, this is neither DRY nor foolproof.

Solution details

There are several solutions to determine the active link. Excluding JavaScript-based approaches, they can be mainly grouped into template-only and custom tag-based solutions.

In every template, you will need to include the following line (or inherit it):

{% include "_navbar.html" with active_link='link2' %}

The _navbar.html file contains the navigation menu with set of checks for the active_link variable:

{% _navbar.html %}

<ul class="nav nav-pills">
    <li {% if active_link == "link1" %} class="active" {% endif %}>
        <a href="{% url 'link1 %}">Link1</a>
    </li>
    <li {% if active_link == "link2" %} class="active" {% endif %}>
        <a href="{% url 'link2 %}">Link2</a>
    </li>
    <li {% if active_link == "link3" %} class="active" {% endif %}>
        <a href="{% url 'link3 %}">Link3</a>
    </li>
</ul>

Django templates offer a versatile set of built-in tags. It is quite easy to create your own custom tag. Since custom tags live inside an app, create a templatetags directory inside an app. This directory must be a package, so it should have an (empty) __init__.py file.

Next, write your custom template in an appropriately named Python file. For example, for this active link pattern, we can create a file called nav.py with the following contents:

# app/templatetags/nav.py

# depreciate in django4
# from django.core.urlresolvers import resolve

from django.template import Library

register = Library()

@register.simple_tag
def active_nav(request, url):
    url_name = resolve(request.path).url_name

    if url_name == url:
        return "active"
    return ""

The syntax for calling this custom tag in a template is {% active_nav request 'pattern_name' %}. Notice that the request needs to be passed in every page that this tag is used.

{# base.html #}

{% load_nav %}
<ul class="nav nav-pills">
    <li class={% active_nav request 'active1' %}>
        <a href="{% url 'active1' %}">Active 1</a>
    </li>
    <li class={% active_nav request 'active2' %}>
        <a href="{% url 'active2' %}">Active 2</a>
    </li>
</ul>

Practical

Note

<ul class="menu-section">
    <li class="menu-item-has-children">

        {% if request.path == '/' %}
            <a href="#business">Business</a> <i class="ion ion-ios-arrow-down dropdown-icon"></i>
        {% else %}
            <a href="{% url 'business:inner' %}">Business</a> <i class="ion ion-ios-arrow-down dropdown-icon"></i>
        {% endif %}

        <div class="menu-subs menu-mega menu-column-4">

            <div class="list-item">
                <h4 class="title">Product & Services</h4>
                <ul>
                    {% for item in header_business %}
                        {% if item.category == '1' %}
                            <li><a href="{% url 'business:item' item.slug %}">{{ item.title }}</a></li>
                        {% endif %}
                    {% endfor %}
                </ul>
            </div>

            <div class="list-item">
                <h4 class="title">Business Consulting</h4>
                <ul>
                    {% for item in header_business %}
                        {% if item.category == '2' %}
                            <li><a href="{% url 'business:item' item.slug %}">{{ item.title }}</a></li>
                        {% endif %}
                    {% endfor %}
                </ul>
            </div>

            <div class="list-item">
                <h4 class="title">IT Services</h4>
                <ul>
                    {% for item in header_business %}
                        {% if item.category == '3' %}
                            <li><a href="{% url 'business:item' item.slug %}">{{ item.title }}</a></li>
                        {% endif %}
                    {% endfor %}
                </ul>
            </div>

        </div>
    </li>

    <li class="menu-item-has-children">
        {% if request.path == '/' %}
          <a href="#about">About us</a>
        {% else %}
          <a href="{% url 'about:inner' %}">About us</a>
        {% endif %}
    </li>

</ul>

Reference