Mike
Mike

Reputation: 505

Django: identify app in template

I have three apps in my Django project that correspond to separate parts of the website. All three parts are accessible from the navigation menu, defined in common base.html template.

I want to be able to identify the app that called the template to add an 'active' css class to the menu option corresponding to the active part of the site.

What's the best way to do it, short of modifying each view to pass an additional variable to the template?

Upvotes: 0

Views: 1144

Answers (3)

Burhan Khalid
Burhan Khalid

Reputation: 174662

The most non-invasive way would be:

  1. Write a template tag that generates your menu.
  2. Update your context with the application name.
  3. Pass this to the template tag and modify the css accordingly.

I'll explain the second bit, as writing custom template tags is covered in detail in the django documentation.

To update the context; we need some middleware. This should do what you need:

class SetApplicationName(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        request.current_app = view_func.__module__.split('.')[0]

Place this somewhere django can find it (in any directory in PYTHONPATH), and add it to your middleware classes. Also, make sure you have django.core.context_processors.request in your template context processors.

In your templates, now you have {{ request.current_app }} which should point the app name.

Your template tag should be something like {% navigation_menu request.current_app %}, and you can then modify your menu css accordingly.

Upvotes: 2

Serhii Holinei
Serhii Holinei

Reputation: 5864

If you define navigation menu in separate template, you could include it with additional context.

base.html:

{% block navigation %}Here will be navigation{% endblock %}

template_from_some_app.html:

{% extends "base.html" %}

{% block navigation %}
    {% include "navigation.html" with active_app='second_app' %}
{% endblock %}

navigation.html:

<ul class="nav">
    <li {% if active_app == 'first_app' %} class="active">{% endif %}>
        First app
    </li>
    <li {% if active_app == 'second_app' %} class="active">{% endif %}>
        Second app
    </li>
    <li {% if active_app == 'third_app' %} class="active">{% endif %}>
        Third app
    </li>
</ul>

Upvotes: 0

xbello
xbello

Reputation: 7443

I would try "overriding" the {%block%} tag.

In your base.html template put something like:

{%block navigation_bar%}
 <div class="regular">First app</div>
 <div class="regular">Second app</div>
 <div class="regular">Third app</div>
{%endblock%}

In your descendant templates, change that navitation_bar block with other. first_app_base.html looks like:

{%extends "base.html"%}

{%block navigation_bar%}
 <div class="active">First app</div>
 <div class="regular">Second app</div>
 <div class="regular">Third app</div>
{%endblock%}

Upvotes: 0

Related Questions