views:

82

answers:

4

I have a parent template that contains a generic navigation menu. I want to be able to add class="selected" to the appropriate menu option.

I want to be able to set a variable in a child template, for example:

{% set menu = "products" %}

and do:

{%ifequal menu "products" %}class="selected"{% endifequal %}

I don't want to set a value in the View because I would have to add this to all my view methods, and I dont want to repeat the entire menu html in each child page because if the menu changes I only want to change the HTML in one place.

Am I approaching this from a “non-Django” mind-set?

Any help would be really appreciated. thanks.

+1  A: 

There is more than one answer here of course!

You could use custom template tags to both draw the menu and select the appropriate one.

So your template tag would be:

{% mymainmenu selecteditem %}

Have a look at the custom template tag documentation on the django site, but it would end up something like:

@register.simple_tag
def mymainmenu(selecteditem):

    html = ''

    build the html for the menu here and include selected class

    return html
There is more than one answer, indeed, but this is the one obvious way to do it. (Though it may not be obvious at first!)
jcdyer
+2  A: 

The context you pass within you view is also available in the templates you're extending. Adding a 'menu_class': 'selected' in the context, you could set

<div id="menu" class="{{ menu_class }}">

in the base template.

Another way around would be

<div id="menu" class="mymenu {% block menu_attrib %}{% endblock %}">

which then is extendible in your child template by

{% block menu_attrib %}selected{% endblock %}
speakman
A: 

Thanks everyone - in the end I followed speakman's suggestion and put the name of the current menu option in thew context and use my:

{%ifequal menu "products" %}class="selected"{% endifequal %}

clause in each menu opton.

I don't think this is a great solution, it couples my 'views' to my 'templates' more than I would have liked...but maybe this is just s django quirk

Tom Carnell
Then hit the check mark next to Speakman's answer. BTW, the Django folks seem to have intentionally prevented `{% extends %}` from setting variables to passed-in values like a function.
Mike DeSimone
+1  A: 

for the record, it is considered a bad practice... but you can do this

{% with "products" as menu %}
    {{ menu }}
{% endwith %}

Since that doesn't actually solve your specific problem here is a possible application...

<div class='menu'>
    {% block menuitems %}
        <a class='{% ifequal menu 'products' %}selected{% endifequal %}' href='/whereever/'>products</a>
        ...
    {% endblock %}
</div>

and in the child template

{% block menuitems %}
    {% with 'products' as menu %}
        {{ block.super }}
    {% endwith %}
{% endblock %}
Jiaaro