How to render menu with one active item with DRY?

sergzach picture sergzach · Mar 20, 2012 · Viewed 32k times · Source

I would like to render a constructions like:

<a href='/home'>Home</a>
<span class='active'>Community</span>
<a href='/about'>About</a>

Where Community is selected menu item. I have menu with same options for several templates but I would not like to create combinations for each template:

<!-- for Home template-->
        <span class='active'>Home</span>
        <a href='/comminuty'>Community</a>
        <a href='/about'>About</a>
    ...
<!-- for Community template-->
        <a href='/home'>Home</a>
        <span class='active'>Community</span>
        <a href='/about'>About</a>
    ...
<!-- for About template-->
        <a href='/home'>Home</a>
        <a href='/community'>Community</a>
        <span class='active'>About</span>

We have permanent list of menu items, so, it can be more effective way - to create only one generalized structure of menu then render menu with required option for template.

For example it could be a tag that allows to do that.

Answer

vincent picture vincent · Dec 9, 2014

Figured out another way to do it, elegant enough thanks to this answer : https://stackoverflow.com/a/17614086/34871

Given an url pattern such as:

url(r'^some-url', "myapp.myview", name='my_view_name'),

my_view_name is available to the template through request ( remember you need to use a RequestContext - which is implicit when using render_to_response )

Then menu items may look like :

<li class="{% if request.resolver_match.url_name == "my_view_name" %}active{% endif %}"><a href="{% url "my_view_name" %}">Shortcut1</a></li>
<li class="{% if request.resolver_match.url_name == "my_view_name2" %}active{% endif %}"><a href="{% url "my_view_name2" %}">Shortcut2</a></li>

etc.

This way, the url can change and it still works if url parameters vary, and you don't need to keep a list of menu items elsewhere.