11

I am trying change the active selection of my navigation links based on the current page where the user is at.

I am trying to do omething like this:

<li {% if request.get_full_path == {% url profile_edit_personal %} %}class="current"{% endif %}><a href="{% url profile_edit_personal %}">Personal Details</a></li>

Alternatively, I know I could define do something like this:

<li class="{% block current %}{% endblock %}"><a href="{% url profile_edit_personal %}">Personal Details</a></li>

and add a {% block current %}current{% endblock %} to each of the relevant templates but I would prefer something like what Im trying to achieve in the first example if possible

Thanks!

3 Answers 3

21

Since you'll probably only need to do this once--in your nav template--it makes more sense to me to keep everything in one place.

First reverse your url names and store them in variables like Timmy suggested, then simply compare them in the template:

{% url 'about_page' as about %}
...

<ul id="nav">
    <li class="{% if request.path == about %}active{% endif %}">
        <a href="{{about}}">About</a>
    </li>
...

Just make sure you have your request context processor enabled so you have access to the request in the template. Do this by adding django.core.context_processors.debug in your TEMPLATE_CONTEXT_PROCESSORS settings variable.

Sign up to request clarification or add additional context in comments.

Comments

6

This is quite a common requirement so it might be worthwhile writing your own template tag to perform this:

class isCurrentNode(template.Node):
    def __init__(self, patterns):
        self.patterns = patterns
    def render(self, context):
        path = context['request'].path
        for pattern in self.patterns:
            curr_pattern = template.Variable(pattern).resolve(context)
            if path == curr_pattern:
        return "current"
            return ""

@register.tag
def is_current(parser, token):
    """ Check if the browse is currently at this supplied url"""
    args = token.split_contents()
    if len(args) < 2:
        raise template.TemplateSyntaxError, "%r tag requires at least one argument" % args[0]
    return isCurrentNode(args[1:])

and in your template

{% url about_page as about %}
{% url home_page as home %}
...

<ul>
    <li class="{% is_current home %}"><a href="{{ home }}">Home</a></li>
    <li class="{% is_current about %}"><a href="{{ about }}">About</a></li>
    ...

Here's the same idea done slightly differently:

http://gnuvince.wordpress.com/2007/09/14/a-django-template-tag-for-the-current-active-page/ http://www.turnkeylinux.org/blog/django-navbar

Comments

3

How about:

<li {% if request.get_full_path == profile_edit_personal.get_absolute_url %}
    class="current"{% endif %}><a href="{% url profile_edit_personal %}">
    Personal Details</a></li>

where get_absolute_url is as discussed in the Django docs.

Its still probably not the best way to customise active nav menu headers though, there's probably some CSS tricks that can do it without as much code. I'd say more but only had half a cup of coffee this morning..

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.