-1

I have my navbar on my base.html, so I extend it on all other pages. But I have a class "active" on the home page, so it also stays active in all other pages.

<ul class="navbar-nav">
    <li class="nav-item">
        <a class="nav-link active" href="http://127.0.0.1:8000/backend/">
            <i class="ni ni-shop text-primary"></i>
            <span class="nav-link-text">Dashboard</span>
        </a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="http://127.0.0.1:8000/backend/clientes">
            <i class="ni ni-ungroup text-orange"></i>
            <span class="nav-link-text">Clients</span>
        </a>
    </li>
</ul>

How can I change the active class to a different menu item based on the page I am?

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
overclock
  • 585
  • 3
  • 20
  • Does this answer your question? [Django - Highlight Navigation based on current page?](https://stackoverflow.com/questions/7665514/django-highlight-navigation-based-on-current-page) – Mihai T Feb 17 '20 at 09:23
  • @MihaiT I have already tried it but it doesn't work. – overclock Feb 17 '20 at 09:32
  • ' it doesn't work ' . What doesn't exactly work ? Anyway, that's an old question/answer. Your current situation might differ slightly but the logic stays the same. I am sure there are dozens of answers on the net on how to solve this requirement – Mihai T Feb 17 '20 at 09:34

3 Answers3

0

There's no one-size-fits-all answer to your question, it really depends on your project's structure, url hierarchy etc. But usually, the best solutions are either a custom template tag taking the request as argument (and/or other context variables or plain constants, depending on your own project's logic) to compute the current "section" and render the navbar accordingly.

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
-1

Send name as variable and value with active.

def index(request):
   # your code


    context = {

        'dashboard': 'active',
    }

    return render(request, 'index.html', context)

def clients(request):
   # your code


    context = {

        'clients': 'active',
    }

    return render(request, 'clients.html', context)

Use variable like this:

<ul class="navbar-nav">
    <li class="nav-item">
        <a class="nav-link {{ dashboard }}" href="http://127.0.0.1:8000/backend/">
            <i class="ni ni-shop text-primary"></i>
            <span class="nav-link-text">Dashboard</span>
        </a>
    </li>
    <li class="nav-item">
        <a class="nav-link {{ clients }}" href="http://127.0.0.1:8000/backend/clientes">
            <i class="ni ni-ungroup text-orange"></i>
            <span class="nav-link-text">Clients</span>
        </a>
    </li>
</ul>
sandeep
  • 721
  • 1
  • 7
  • 14
  • This requires adding specific context values to each and every view... Really not dry. And the chances of name clashes with this exact implementation is very high. – bruno desthuilliers Feb 17 '20 at 12:19
-1

OPTION 1 You can use django contex_processors. add your settings.py

TEMPLATES = [
{
     #other settings
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
     #other settings
    'OPTIONS': {
        'context_processors': [
             #other options
            'context_file_path.defaults',

        ],
    },
},

]

in your context_file.py

def defaults(request):
    active_bar = "" # your active bar logic
    return {
        'active_bar': active_bar,
    }

with this method, each request decide which bar active. And active_bar variable is being passed to your template. In your template you can add active class if active_bar variable equals your bar name. Like that:

<ul class="navbar-nav">
        <li class="nav-item">
          <a class="nav-link {% if active_bar == 'dashboard' %}active{% endif %}" href="http://127.0.0.1:8000/backend/">
            <i class="ni ni-shop text-primary"></i>
            <span class="nav-link-text">Dashboard</span>
          </a>
        </li>
        <li class="nav-item  {% if active_bar == 'clients' %}active{% endif %}">
          <a class="nav-link" href="http://127.0.0.1:8000/backend/clientes">
            <i class="ni ni-ungroup text-orange"></i>
            <span class="nav-link-text">Clients</span>
          </a>
        </li>
      </ul>

OPTION 2

You can write a custom js file and add your base html. In this js file you can detect url and decide active pane. After that you can add active class to list pane.

kamilyrb
  • 2,502
  • 3
  • 10
  • 25
  • Yeah, I think that the js file will be the best choice to solve this. Thanks! – overclock Feb 17 '20 at 09:42
  • Please do NOT advise using context processors for anything else than injecting simple values. Context processors are costly and are systematically invoked for all templates (even those that don't need it), plus they make things automagically appear in the context which is a maintenance hell. – bruno desthuilliers Feb 17 '20 at 12:12
  • Also, you definitly don't need JS to know where you are, the `request` object already has all relevant infos. – bruno desthuilliers Feb 17 '20 at 12:13
  • @JoãodeSousa I very strongly suggest you choose a better solution - a custom template tag comes to mind. – bruno desthuilliers Feb 17 '20 at 12:21