How to render menu with one active item with DRY?












34















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.










share|improve this question



























    34















    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.










    share|improve this question

























      34












      34








      34


      18






      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.










      share|improve this question














      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.







      django django-templates






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 20 '12 at 19:28









      sergzachsergzach

      3,83653265




      3,83653265
























          10 Answers
          10






          active

          oldest

          votes


















          57














          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.






          share|improve this answer





















          • 1





            just wanted to say that this is perfect because it allows you to use this in a single 'global' template instead of implementing the same thing several times in individual template files. thanks

            – Jack
            Sep 2 '15 at 22:20






          • 1





            request.resolver_match.url_name does not return a namespaced name.

            – Flimm
            May 13 '16 at 12:09






          • 1





            use request.resolver_match.view_name for namespaced name

            – zhenming
            Jul 13 '16 at 4:55








          • 4





            This is an excellent solution. Much easier and more elegant than the others.

            – larapsodia
            Aug 29 '16 at 1:43






          • 1





            This answer is the cleanest to implement. I read many posts on the forum and they are pulling off complicated solutions, but for most of us that are not going to develop a very big app this works just like a charm. I'd like to add one thing: most likely, one will need to have 2 class names in the html, one for styling the menu items if they are not selected, and one for the case they are selected/active. I give an example in the next comment.

            – Ibo
            Sep 29 '17 at 17:44





















          45














          Using template tag



          You can simply use the following template tag:



          # path/to/templatetags/mytags.py
          import re

          from django import template
          from django.core.urlresolvers import reverse, NoReverseMatch

          register = template.Library()


          @register.simple_tag(takes_context=True)
          def active(context, pattern_or_urlname):
          try:
          pattern = '^' + reverse(pattern_or_urlname)
          except NoReverseMatch:
          pattern = pattern_or_urlname
          path = context['request'].path
          if re.search(pattern, path):
          return 'active'
          return ''


          So, in you your template:



          {% load mytags %}
          <nav><ul>
          <li class="nav-home {% active 'url-name' %}"><a href="#">Home</a></li>
          <li class="nav-blog {% active '^/regex/' %}"><a href="#">Blog</a></li>
          </ul></nav>


          Using only HTML & CSS



          There is another approach, using only HTML & CSS, that you can use in any framework or static sites.



          Considering you have a navigation menu like this one:



          <nav><ul>
          <li class="nav-home"><a href="#">Home</a></li>
          <li class="nav-blog"><a href="#">Blog</a></li>
          <li class="nav-contact"><a href="#">Contact</a></li>
          </ul></nav>


          Create some base templates, one for each session of your site, as for example:



          home.html
          base_blog.html
          base_contact.html


          All these templates extending base.html with a block "section", as for example:



          ...
          <body id="{% block section %}section-generic{% endblock %}">
          ...


          Then, taking the base_blog.html as example, you must have the following:



          {% extends "base.html" %}
          {% block section %}section-blog{% endblock %}


          Now it is easy to define the actived menu item using CSS only:



          #section-home .nav-home,
          #section-blog .nav-blog,
          #section-contact .nav-contact { background-color: #ccc; }





          share|improve this answer





















          • 3





            I wanted exact match, so I modified the pattern to: pattern = '^' + reverse(pattern_or_urlname) + '$'.

            – daigorocub
            Aug 7 '14 at 10:49













          • @daigorocub so you broke the example below. You can provide a ^ like in {% active '^/regex/' %}. I think we must revert your edit. ;)

            – semente
            Aug 8 '14 at 13:40








          • 1





            Well, this post really helped me but I had to add the $ sign for my code to work and I believe it adds something to the answer, no?. I didn't use the whole example - just needed the first part. Thanks.

            – daigorocub
            Aug 9 '14 at 10:44






          • 1





            Thank you for inspiration. I have modified your code to work even with I18N pattern, that has language prefixed path. You can edit your comment if you like, so that others can benefit from this. pastebin.com/8hegST6b

            – darkless
            Aug 20 '14 at 19:12













          • The template tag method is nice! I added an exact parameter to the active tag, adding a trailing $ to the regex, because when you're linking to the index url '/', the link would always be active, since all urls start with /

            – phoibos
            Jun 18 '17 at 12:55



















          27














          I found easy and elegant DRY solution.



          It's the snippet:
          http://djangosnippets.org/snippets/2421/



          **Placed in templates/includes/tabs.html**

          <ul class="tab-menu">
          <li class="{% if active_tab == 'tab1' %} active{% endif %}"><a href="#">Tab 1</a></li>
          <li class="{% if active_tab == 'tab2' %} active{% endif %}"><a href="#">Tab 2</a></li>
          <li class="{% if active_tab == 'tab3' %} active{% endif %}"><a href="#">Tab 3</a></li>
          </ul>

          **Placed in your page template**

          {% include "includes/tabs.html" with active_tab='tab1' %}





          share|improve this answer





















          • 1





            How to incorporate this approach if I use {% extends "includes/tabs.html" %} to create desired layouts?

            – Evgeny Bobkin
            Jan 3 '18 at 11:41











          • Why we should include tabs in every page template? It is not DRY solution, I think...

            – Abdüssamet ASLAN
            Aug 12 '18 at 13:03



















          4














          You could make a context variable links with the name, URL and whether it's an active item:



          {% for name, url, active in links %}
          {% if active %}
          <span class='active'>{{ name }}</span>
          {% else %}
          <a href='{{ url }}'>{{ name }}</a>
          {% endif %}
          {% endfor %}


          If this menu is present on all pages, you could use a context processor:



          def menu_links(request):
          links =
          # write code here to construct links
          return { 'links': links }


          Then, in your settings file, add that function to TEMPLATE_CONTEXT_PROCESSORS as follows: path.to.where.that.function.is.located.menu_links. This means the function menu_links will be called for every template and that means the variable links is available in each template.






          share|improve this answer


























          • What do you mean for 3 variables in for loop? for name, url, active. Is this correct to use 3 variables?

            – sergzach
            Mar 20 '12 at 19:45













          • The name is the name of the link (for example, Home), the url is the URL to where the link goes and active is whether the page is currently active. You can compute this for each page and you would get a list of links, such as [("Home", "/home", True), ("Community", "/community", False), ("About", "/about", False)].

            – Simeon Visser
            Mar 20 '12 at 19:48






          • 1





            It´s indeed possible to use three variables. You can read the documentation of a for loop in Django here: docs.djangoproject.com/en/1.3/ref/templates/builtins/#for (see their example with points).

            – Simeon Visser
            Mar 20 '12 at 20:02











          • This is exactly the solution I came up with. It seems the elegance of python and the power of context processors often goes out the window when it comes to templates, so I like this solution.

            – andyhasit
            Jul 2 '17 at 0:37



















          1














          Assuming the nav item is a link with the same URL as the current page, you could just use JavaScript. Here's an annotated method that I use to add a class="active" to a li in a navigation menu with class="nav":



          // Get the path name (the part directly after the URL) and append a trailing slash
          // For example, 'http://www.example.com/subpage1/sub-subpage/'
          // would become '/subpage1/'
          var pathName = '/' + window.location.pathname.split('/')[1];
          if ( pathName != '/' ) { pathName = pathName + '/'; }

          // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
          // This returns a top-level nav item
          var url = window.location.protocol + '//' +
          window.location.host +
          pathName;
          console.log(url);

          // Add an 'active' class to the navigation list item that contains this url
          var $links = document.querySelectorAll('.nav a');
          $link = Array.prototype.filter.call( $links, function(el) {
          return el.href === url;
          })[0];
          $link.parentNode.className += ' active';


          This method means you can simply pop it into your base template once and forget about it. No repetition, and no manual specification of the page URL in each template.



          One caveat: this obviously only works if the url found matches a navigation link href. It would additionally be possible to specify a couple of special use cases in the JS, or target a different parent element as needed.



          Here's a runnable example (keep in mind, snippets run on StackSnippets):






          // Get the path name (the part directly after the URL) and append a trailing slash
          // For example, 'http://www.example.com/subpage1/sub-subpage/'
          // would become '/subpage1/'
          var pathName = '/' + window.location.pathname.split('/')[1];
          if ( pathName != '/' ) { pathName = pathName + '/'; }

          // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
          // This returns a top-level nav item
          var url = window.location.protocol + '//' +
          window.location.host +
          pathName;
          console.log(url);

          // Add an 'active' class to the navigation list item that contains this url
          var $links = document.querySelectorAll('.nav a');
          $link = Array.prototype.filter.call( $links, function(el) {
          return el.href === url;
          })[0];
          $link.parentNode.className += ' active';

          li {
          display: inline-block;
          margin: 0 10px;
          }
          a {
          color: black;
          text-decoration: none;
          }
          .active a {
          color: red;
          }

          <ul class="nav">
          <li>
          <a href="http://example.com/">Example Link</a>
          </li>
          <li>
          <a href="http://stacksnippets.net/js/">This Snippet</a>
          </li>
          <li>
          <a href="https://google.com/">Google</a>
          </li>
          <li>
          <a href="http://stackoverflow.com/">StackOverflow</a>
          </li>
          </ul>








          share|improve this answer

































            1














            Here ist my solution:



            {% url 'module:list' as list_url %}
            {% url 'module:create' as create_url %}

            <ul>
            <li><a href="{% url 'module:list' %}" class="{% if request.path == list_url %}active{% endif %}">List Page</a></li>
            <li><a href="{% url 'module:create' %}" class="{% if request.path == create_url %}active{% endif %}">Creation Page</a></li>
            </ul>





            share|improve this answer































              0














              Based on @vincent's answer, there is an easier way to do this without messing up with django url patterns.



              The current request path can be checked against the rendered menu item path, and if they match then this is the active item.



              In the following example I use django-mptt to render the menu but one can replace node.path with each menu item path.



              <li class="{% if node.path == request.path %}active{% endif %}">
              <a href="node.path">node.title</a>
              </li>





              share|improve this answer































                0














                I ran into this challenge today with how to dynamically activate a "category" in a sidebar. The categories have slugs which are from the DB.



                I solved it by checking to see category slug was in the current path. The slugs are unique (standard practice) so I think this should work without any conflicts.



                {% if category.slug in request.path %}active{% endif %}


                Full example code of the loop to get the categories and activate the current one.



                {% for category in categories %}
                <a class="list-group-item {% if category.slug in request.path %}active{% endif %}" href="{% url 'help:category_index' category.slug %}">
                <span class="badge">{{ category.article_set.count }}</span>
                {{ category.title }}
                </a>
                {% endfor %}





                share|improve this answer
























                • I can see this go wrong. For instance, one slug being amazing, and another being amazing_stuff. The unique constraint is satisfied, and yet category.slug in request.path will be true on both pages for amazing.

                  – Flimm
                  May 13 '16 at 12:11



















                0














                I am using an easier and pure CSS solution. It has its limitations, of which I know and can live with, but it avoids clumsy CSS class selectors, like this:





                <a href="index.html" class="item{% if url == request.path %}active{% endif %}">index</a>


                Because a space character before active is missing the class selector gets called itemactive instead of item active and this isn't exactly too difficult to get wrong like that.



                For me this pure CSS solution works much better:





                a.item /* all menu items are of this class */
                {
                color: black;
                text-decoration: none;
                }

                a.item[href~="{{ request.path }}"] /* just the one which is selected matches */
                {
                color: red;
                text-decoration: underline;
                }


                Notice: This even works if the URL has additional path components, because then href also matches partially. That could eventually cause 'collisions' with more than one match, but often enough it just works, because on well structured websites a "subdirectory" of an URL usually is a child of the selected menu item.






                share|improve this answer































                  0














                  I have come up with a way to utilize block tags within menu-containing parent template to achieve something like this.



                  base.html - the parent template:



                  <a href="/" class="{% block menu_home_class %}{% endblock %}">Home</a>
                  <a href="/about" class="{% block menu_about_class %}{% endblock %}">About</a>
                  <a href="/contact" class="{% block menu_contact_class %}{% endblock %}">Contact</a>

                  {% block content %}{% endblock %}


                  about.html - template for a specific page:



                  {% extends "base.html" %}

                  {% block menu_about_class %}active{% endblock %}

                  {% block content %}
                  About page content...
                  {% endblock %}


                  As you can see, the thing that varies between different page templates is the name of the block containing active. contact.html would make use of menu_contact_class, and so on.



                  One benefit of this approach is that you can have multiple subpages with the same active menu item. For example, an about page might have subpages giving information about each team members of a company. It could make sense to have the About menu item stay active for each of these subpages.






                  share|improve this answer
























                    Your Answer






                    StackExchange.ifUsing("editor", function () {
                    StackExchange.using("externalEditor", function () {
                    StackExchange.using("snippets", function () {
                    StackExchange.snippets.init();
                    });
                    });
                    }, "code-snippets");

                    StackExchange.ready(function() {
                    var channelOptions = {
                    tags: "".split(" "),
                    id: "1"
                    };
                    initTagRenderer("".split(" "), "".split(" "), channelOptions);

                    StackExchange.using("externalEditor", function() {
                    // Have to fire editor after snippets, if snippets enabled
                    if (StackExchange.settings.snippets.snippetsEnabled) {
                    StackExchange.using("snippets", function() {
                    createEditor();
                    });
                    }
                    else {
                    createEditor();
                    }
                    });

                    function createEditor() {
                    StackExchange.prepareEditor({
                    heartbeatType: 'answer',
                    autoActivateHeartbeat: false,
                    convertImagesToLinks: true,
                    noModals: true,
                    showLowRepImageUploadWarning: true,
                    reputationToPostImages: 10,
                    bindNavPrevention: true,
                    postfix: "",
                    imageUploader: {
                    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                    allowUrls: true
                    },
                    onDemand: true,
                    discardSelector: ".discard-answer"
                    ,immediatelyShowMarkdownHelp:true
                    });


                    }
                    });














                    draft saved

                    draft discarded


















                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9793576%2fhow-to-render-menu-with-one-active-item-with-dry%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown

























                    10 Answers
                    10






                    active

                    oldest

                    votes








                    10 Answers
                    10






                    active

                    oldest

                    votes









                    active

                    oldest

                    votes






                    active

                    oldest

                    votes









                    57














                    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.






                    share|improve this answer





















                    • 1





                      just wanted to say that this is perfect because it allows you to use this in a single 'global' template instead of implementing the same thing several times in individual template files. thanks

                      – Jack
                      Sep 2 '15 at 22:20






                    • 1





                      request.resolver_match.url_name does not return a namespaced name.

                      – Flimm
                      May 13 '16 at 12:09






                    • 1





                      use request.resolver_match.view_name for namespaced name

                      – zhenming
                      Jul 13 '16 at 4:55








                    • 4





                      This is an excellent solution. Much easier and more elegant than the others.

                      – larapsodia
                      Aug 29 '16 at 1:43






                    • 1





                      This answer is the cleanest to implement. I read many posts on the forum and they are pulling off complicated solutions, but for most of us that are not going to develop a very big app this works just like a charm. I'd like to add one thing: most likely, one will need to have 2 class names in the html, one for styling the menu items if they are not selected, and one for the case they are selected/active. I give an example in the next comment.

                      – Ibo
                      Sep 29 '17 at 17:44


















                    57














                    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.






                    share|improve this answer





















                    • 1





                      just wanted to say that this is perfect because it allows you to use this in a single 'global' template instead of implementing the same thing several times in individual template files. thanks

                      – Jack
                      Sep 2 '15 at 22:20






                    • 1





                      request.resolver_match.url_name does not return a namespaced name.

                      – Flimm
                      May 13 '16 at 12:09






                    • 1





                      use request.resolver_match.view_name for namespaced name

                      – zhenming
                      Jul 13 '16 at 4:55








                    • 4





                      This is an excellent solution. Much easier and more elegant than the others.

                      – larapsodia
                      Aug 29 '16 at 1:43






                    • 1





                      This answer is the cleanest to implement. I read many posts on the forum and they are pulling off complicated solutions, but for most of us that are not going to develop a very big app this works just like a charm. I'd like to add one thing: most likely, one will need to have 2 class names in the html, one for styling the menu items if they are not selected, and one for the case they are selected/active. I give an example in the next comment.

                      – Ibo
                      Sep 29 '17 at 17:44
















                    57












                    57








                    57







                    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.






                    share|improve this answer















                    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.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited May 23 '17 at 12:25









                    Community

                    11




                    11










                    answered Dec 9 '14 at 12:35









                    vincentvincent

                    4,34322220




                    4,34322220








                    • 1





                      just wanted to say that this is perfect because it allows you to use this in a single 'global' template instead of implementing the same thing several times in individual template files. thanks

                      – Jack
                      Sep 2 '15 at 22:20






                    • 1





                      request.resolver_match.url_name does not return a namespaced name.

                      – Flimm
                      May 13 '16 at 12:09






                    • 1





                      use request.resolver_match.view_name for namespaced name

                      – zhenming
                      Jul 13 '16 at 4:55








                    • 4





                      This is an excellent solution. Much easier and more elegant than the others.

                      – larapsodia
                      Aug 29 '16 at 1:43






                    • 1





                      This answer is the cleanest to implement. I read many posts on the forum and they are pulling off complicated solutions, but for most of us that are not going to develop a very big app this works just like a charm. I'd like to add one thing: most likely, one will need to have 2 class names in the html, one for styling the menu items if they are not selected, and one for the case they are selected/active. I give an example in the next comment.

                      – Ibo
                      Sep 29 '17 at 17:44
















                    • 1





                      just wanted to say that this is perfect because it allows you to use this in a single 'global' template instead of implementing the same thing several times in individual template files. thanks

                      – Jack
                      Sep 2 '15 at 22:20






                    • 1





                      request.resolver_match.url_name does not return a namespaced name.

                      – Flimm
                      May 13 '16 at 12:09






                    • 1





                      use request.resolver_match.view_name for namespaced name

                      – zhenming
                      Jul 13 '16 at 4:55








                    • 4





                      This is an excellent solution. Much easier and more elegant than the others.

                      – larapsodia
                      Aug 29 '16 at 1:43






                    • 1





                      This answer is the cleanest to implement. I read many posts on the forum and they are pulling off complicated solutions, but for most of us that are not going to develop a very big app this works just like a charm. I'd like to add one thing: most likely, one will need to have 2 class names in the html, one for styling the menu items if they are not selected, and one for the case they are selected/active. I give an example in the next comment.

                      – Ibo
                      Sep 29 '17 at 17:44










                    1




                    1





                    just wanted to say that this is perfect because it allows you to use this in a single 'global' template instead of implementing the same thing several times in individual template files. thanks

                    – Jack
                    Sep 2 '15 at 22:20





                    just wanted to say that this is perfect because it allows you to use this in a single 'global' template instead of implementing the same thing several times in individual template files. thanks

                    – Jack
                    Sep 2 '15 at 22:20




                    1




                    1





                    request.resolver_match.url_name does not return a namespaced name.

                    – Flimm
                    May 13 '16 at 12:09





                    request.resolver_match.url_name does not return a namespaced name.

                    – Flimm
                    May 13 '16 at 12:09




                    1




                    1





                    use request.resolver_match.view_name for namespaced name

                    – zhenming
                    Jul 13 '16 at 4:55







                    use request.resolver_match.view_name for namespaced name

                    – zhenming
                    Jul 13 '16 at 4:55






                    4




                    4





                    This is an excellent solution. Much easier and more elegant than the others.

                    – larapsodia
                    Aug 29 '16 at 1:43





                    This is an excellent solution. Much easier and more elegant than the others.

                    – larapsodia
                    Aug 29 '16 at 1:43




                    1




                    1





                    This answer is the cleanest to implement. I read many posts on the forum and they are pulling off complicated solutions, but for most of us that are not going to develop a very big app this works just like a charm. I'd like to add one thing: most likely, one will need to have 2 class names in the html, one for styling the menu items if they are not selected, and one for the case they are selected/active. I give an example in the next comment.

                    – Ibo
                    Sep 29 '17 at 17:44







                    This answer is the cleanest to implement. I read many posts on the forum and they are pulling off complicated solutions, but for most of us that are not going to develop a very big app this works just like a charm. I'd like to add one thing: most likely, one will need to have 2 class names in the html, one for styling the menu items if they are not selected, and one for the case they are selected/active. I give an example in the next comment.

                    – Ibo
                    Sep 29 '17 at 17:44















                    45














                    Using template tag



                    You can simply use the following template tag:



                    # path/to/templatetags/mytags.py
                    import re

                    from django import template
                    from django.core.urlresolvers import reverse, NoReverseMatch

                    register = template.Library()


                    @register.simple_tag(takes_context=True)
                    def active(context, pattern_or_urlname):
                    try:
                    pattern = '^' + reverse(pattern_or_urlname)
                    except NoReverseMatch:
                    pattern = pattern_or_urlname
                    path = context['request'].path
                    if re.search(pattern, path):
                    return 'active'
                    return ''


                    So, in you your template:



                    {% load mytags %}
                    <nav><ul>
                    <li class="nav-home {% active 'url-name' %}"><a href="#">Home</a></li>
                    <li class="nav-blog {% active '^/regex/' %}"><a href="#">Blog</a></li>
                    </ul></nav>


                    Using only HTML & CSS



                    There is another approach, using only HTML & CSS, that you can use in any framework or static sites.



                    Considering you have a navigation menu like this one:



                    <nav><ul>
                    <li class="nav-home"><a href="#">Home</a></li>
                    <li class="nav-blog"><a href="#">Blog</a></li>
                    <li class="nav-contact"><a href="#">Contact</a></li>
                    </ul></nav>


                    Create some base templates, one for each session of your site, as for example:



                    home.html
                    base_blog.html
                    base_contact.html


                    All these templates extending base.html with a block "section", as for example:



                    ...
                    <body id="{% block section %}section-generic{% endblock %}">
                    ...


                    Then, taking the base_blog.html as example, you must have the following:



                    {% extends "base.html" %}
                    {% block section %}section-blog{% endblock %}


                    Now it is easy to define the actived menu item using CSS only:



                    #section-home .nav-home,
                    #section-blog .nav-blog,
                    #section-contact .nav-contact { background-color: #ccc; }





                    share|improve this answer





















                    • 3





                      I wanted exact match, so I modified the pattern to: pattern = '^' + reverse(pattern_or_urlname) + '$'.

                      – daigorocub
                      Aug 7 '14 at 10:49













                    • @daigorocub so you broke the example below. You can provide a ^ like in {% active '^/regex/' %}. I think we must revert your edit. ;)

                      – semente
                      Aug 8 '14 at 13:40








                    • 1





                      Well, this post really helped me but I had to add the $ sign for my code to work and I believe it adds something to the answer, no?. I didn't use the whole example - just needed the first part. Thanks.

                      – daigorocub
                      Aug 9 '14 at 10:44






                    • 1





                      Thank you for inspiration. I have modified your code to work even with I18N pattern, that has language prefixed path. You can edit your comment if you like, so that others can benefit from this. pastebin.com/8hegST6b

                      – darkless
                      Aug 20 '14 at 19:12













                    • The template tag method is nice! I added an exact parameter to the active tag, adding a trailing $ to the regex, because when you're linking to the index url '/', the link would always be active, since all urls start with /

                      – phoibos
                      Jun 18 '17 at 12:55
















                    45














                    Using template tag



                    You can simply use the following template tag:



                    # path/to/templatetags/mytags.py
                    import re

                    from django import template
                    from django.core.urlresolvers import reverse, NoReverseMatch

                    register = template.Library()


                    @register.simple_tag(takes_context=True)
                    def active(context, pattern_or_urlname):
                    try:
                    pattern = '^' + reverse(pattern_or_urlname)
                    except NoReverseMatch:
                    pattern = pattern_or_urlname
                    path = context['request'].path
                    if re.search(pattern, path):
                    return 'active'
                    return ''


                    So, in you your template:



                    {% load mytags %}
                    <nav><ul>
                    <li class="nav-home {% active 'url-name' %}"><a href="#">Home</a></li>
                    <li class="nav-blog {% active '^/regex/' %}"><a href="#">Blog</a></li>
                    </ul></nav>


                    Using only HTML & CSS



                    There is another approach, using only HTML & CSS, that you can use in any framework or static sites.



                    Considering you have a navigation menu like this one:



                    <nav><ul>
                    <li class="nav-home"><a href="#">Home</a></li>
                    <li class="nav-blog"><a href="#">Blog</a></li>
                    <li class="nav-contact"><a href="#">Contact</a></li>
                    </ul></nav>


                    Create some base templates, one for each session of your site, as for example:



                    home.html
                    base_blog.html
                    base_contact.html


                    All these templates extending base.html with a block "section", as for example:



                    ...
                    <body id="{% block section %}section-generic{% endblock %}">
                    ...


                    Then, taking the base_blog.html as example, you must have the following:



                    {% extends "base.html" %}
                    {% block section %}section-blog{% endblock %}


                    Now it is easy to define the actived menu item using CSS only:



                    #section-home .nav-home,
                    #section-blog .nav-blog,
                    #section-contact .nav-contact { background-color: #ccc; }





                    share|improve this answer





















                    • 3





                      I wanted exact match, so I modified the pattern to: pattern = '^' + reverse(pattern_or_urlname) + '$'.

                      – daigorocub
                      Aug 7 '14 at 10:49













                    • @daigorocub so you broke the example below. You can provide a ^ like in {% active '^/regex/' %}. I think we must revert your edit. ;)

                      – semente
                      Aug 8 '14 at 13:40








                    • 1





                      Well, this post really helped me but I had to add the $ sign for my code to work and I believe it adds something to the answer, no?. I didn't use the whole example - just needed the first part. Thanks.

                      – daigorocub
                      Aug 9 '14 at 10:44






                    • 1





                      Thank you for inspiration. I have modified your code to work even with I18N pattern, that has language prefixed path. You can edit your comment if you like, so that others can benefit from this. pastebin.com/8hegST6b

                      – darkless
                      Aug 20 '14 at 19:12













                    • The template tag method is nice! I added an exact parameter to the active tag, adding a trailing $ to the regex, because when you're linking to the index url '/', the link would always be active, since all urls start with /

                      – phoibos
                      Jun 18 '17 at 12:55














                    45












                    45








                    45







                    Using template tag



                    You can simply use the following template tag:



                    # path/to/templatetags/mytags.py
                    import re

                    from django import template
                    from django.core.urlresolvers import reverse, NoReverseMatch

                    register = template.Library()


                    @register.simple_tag(takes_context=True)
                    def active(context, pattern_or_urlname):
                    try:
                    pattern = '^' + reverse(pattern_or_urlname)
                    except NoReverseMatch:
                    pattern = pattern_or_urlname
                    path = context['request'].path
                    if re.search(pattern, path):
                    return 'active'
                    return ''


                    So, in you your template:



                    {% load mytags %}
                    <nav><ul>
                    <li class="nav-home {% active 'url-name' %}"><a href="#">Home</a></li>
                    <li class="nav-blog {% active '^/regex/' %}"><a href="#">Blog</a></li>
                    </ul></nav>


                    Using only HTML & CSS



                    There is another approach, using only HTML & CSS, that you can use in any framework or static sites.



                    Considering you have a navigation menu like this one:



                    <nav><ul>
                    <li class="nav-home"><a href="#">Home</a></li>
                    <li class="nav-blog"><a href="#">Blog</a></li>
                    <li class="nav-contact"><a href="#">Contact</a></li>
                    </ul></nav>


                    Create some base templates, one for each session of your site, as for example:



                    home.html
                    base_blog.html
                    base_contact.html


                    All these templates extending base.html with a block "section", as for example:



                    ...
                    <body id="{% block section %}section-generic{% endblock %}">
                    ...


                    Then, taking the base_blog.html as example, you must have the following:



                    {% extends "base.html" %}
                    {% block section %}section-blog{% endblock %}


                    Now it is easy to define the actived menu item using CSS only:



                    #section-home .nav-home,
                    #section-blog .nav-blog,
                    #section-contact .nav-contact { background-color: #ccc; }





                    share|improve this answer















                    Using template tag



                    You can simply use the following template tag:



                    # path/to/templatetags/mytags.py
                    import re

                    from django import template
                    from django.core.urlresolvers import reverse, NoReverseMatch

                    register = template.Library()


                    @register.simple_tag(takes_context=True)
                    def active(context, pattern_or_urlname):
                    try:
                    pattern = '^' + reverse(pattern_or_urlname)
                    except NoReverseMatch:
                    pattern = pattern_or_urlname
                    path = context['request'].path
                    if re.search(pattern, path):
                    return 'active'
                    return ''


                    So, in you your template:



                    {% load mytags %}
                    <nav><ul>
                    <li class="nav-home {% active 'url-name' %}"><a href="#">Home</a></li>
                    <li class="nav-blog {% active '^/regex/' %}"><a href="#">Blog</a></li>
                    </ul></nav>


                    Using only HTML & CSS



                    There is another approach, using only HTML & CSS, that you can use in any framework or static sites.



                    Considering you have a navigation menu like this one:



                    <nav><ul>
                    <li class="nav-home"><a href="#">Home</a></li>
                    <li class="nav-blog"><a href="#">Blog</a></li>
                    <li class="nav-contact"><a href="#">Contact</a></li>
                    </ul></nav>


                    Create some base templates, one for each session of your site, as for example:



                    home.html
                    base_blog.html
                    base_contact.html


                    All these templates extending base.html with a block "section", as for example:



                    ...
                    <body id="{% block section %}section-generic{% endblock %}">
                    ...


                    Then, taking the base_blog.html as example, you must have the following:



                    {% extends "base.html" %}
                    {% block section %}section-blog{% endblock %}


                    Now it is easy to define the actived menu item using CSS only:



                    #section-home .nav-home,
                    #section-blog .nav-blog,
                    #section-contact .nav-contact { background-color: #ccc; }






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Oct 6 '16 at 13:00

























                    answered Sep 12 '13 at 18:58









                    sementesemente

                    4,86322731




                    4,86322731








                    • 3





                      I wanted exact match, so I modified the pattern to: pattern = '^' + reverse(pattern_or_urlname) + '$'.

                      – daigorocub
                      Aug 7 '14 at 10:49













                    • @daigorocub so you broke the example below. You can provide a ^ like in {% active '^/regex/' %}. I think we must revert your edit. ;)

                      – semente
                      Aug 8 '14 at 13:40








                    • 1





                      Well, this post really helped me but I had to add the $ sign for my code to work and I believe it adds something to the answer, no?. I didn't use the whole example - just needed the first part. Thanks.

                      – daigorocub
                      Aug 9 '14 at 10:44






                    • 1





                      Thank you for inspiration. I have modified your code to work even with I18N pattern, that has language prefixed path. You can edit your comment if you like, so that others can benefit from this. pastebin.com/8hegST6b

                      – darkless
                      Aug 20 '14 at 19:12













                    • The template tag method is nice! I added an exact parameter to the active tag, adding a trailing $ to the regex, because when you're linking to the index url '/', the link would always be active, since all urls start with /

                      – phoibos
                      Jun 18 '17 at 12:55














                    • 3





                      I wanted exact match, so I modified the pattern to: pattern = '^' + reverse(pattern_or_urlname) + '$'.

                      – daigorocub
                      Aug 7 '14 at 10:49













                    • @daigorocub so you broke the example below. You can provide a ^ like in {% active '^/regex/' %}. I think we must revert your edit. ;)

                      – semente
                      Aug 8 '14 at 13:40








                    • 1





                      Well, this post really helped me but I had to add the $ sign for my code to work and I believe it adds something to the answer, no?. I didn't use the whole example - just needed the first part. Thanks.

                      – daigorocub
                      Aug 9 '14 at 10:44






                    • 1





                      Thank you for inspiration. I have modified your code to work even with I18N pattern, that has language prefixed path. You can edit your comment if you like, so that others can benefit from this. pastebin.com/8hegST6b

                      – darkless
                      Aug 20 '14 at 19:12













                    • The template tag method is nice! I added an exact parameter to the active tag, adding a trailing $ to the regex, because when you're linking to the index url '/', the link would always be active, since all urls start with /

                      – phoibos
                      Jun 18 '17 at 12:55








                    3




                    3





                    I wanted exact match, so I modified the pattern to: pattern = '^' + reverse(pattern_or_urlname) + '$'.

                    – daigorocub
                    Aug 7 '14 at 10:49







                    I wanted exact match, so I modified the pattern to: pattern = '^' + reverse(pattern_or_urlname) + '$'.

                    – daigorocub
                    Aug 7 '14 at 10:49















                    @daigorocub so you broke the example below. You can provide a ^ like in {% active '^/regex/' %}. I think we must revert your edit. ;)

                    – semente
                    Aug 8 '14 at 13:40







                    @daigorocub so you broke the example below. You can provide a ^ like in {% active '^/regex/' %}. I think we must revert your edit. ;)

                    – semente
                    Aug 8 '14 at 13:40






                    1




                    1





                    Well, this post really helped me but I had to add the $ sign for my code to work and I believe it adds something to the answer, no?. I didn't use the whole example - just needed the first part. Thanks.

                    – daigorocub
                    Aug 9 '14 at 10:44





                    Well, this post really helped me but I had to add the $ sign for my code to work and I believe it adds something to the answer, no?. I didn't use the whole example - just needed the first part. Thanks.

                    – daigorocub
                    Aug 9 '14 at 10:44




                    1




                    1





                    Thank you for inspiration. I have modified your code to work even with I18N pattern, that has language prefixed path. You can edit your comment if you like, so that others can benefit from this. pastebin.com/8hegST6b

                    – darkless
                    Aug 20 '14 at 19:12







                    Thank you for inspiration. I have modified your code to work even with I18N pattern, that has language prefixed path. You can edit your comment if you like, so that others can benefit from this. pastebin.com/8hegST6b

                    – darkless
                    Aug 20 '14 at 19:12















                    The template tag method is nice! I added an exact parameter to the active tag, adding a trailing $ to the regex, because when you're linking to the index url '/', the link would always be active, since all urls start with /

                    – phoibos
                    Jun 18 '17 at 12:55





                    The template tag method is nice! I added an exact parameter to the active tag, adding a trailing $ to the regex, because when you're linking to the index url '/', the link would always be active, since all urls start with /

                    – phoibos
                    Jun 18 '17 at 12:55











                    27














                    I found easy and elegant DRY solution.



                    It's the snippet:
                    http://djangosnippets.org/snippets/2421/



                    **Placed in templates/includes/tabs.html**

                    <ul class="tab-menu">
                    <li class="{% if active_tab == 'tab1' %} active{% endif %}"><a href="#">Tab 1</a></li>
                    <li class="{% if active_tab == 'tab2' %} active{% endif %}"><a href="#">Tab 2</a></li>
                    <li class="{% if active_tab == 'tab3' %} active{% endif %}"><a href="#">Tab 3</a></li>
                    </ul>

                    **Placed in your page template**

                    {% include "includes/tabs.html" with active_tab='tab1' %}





                    share|improve this answer





















                    • 1





                      How to incorporate this approach if I use {% extends "includes/tabs.html" %} to create desired layouts?

                      – Evgeny Bobkin
                      Jan 3 '18 at 11:41











                    • Why we should include tabs in every page template? It is not DRY solution, I think...

                      – Abdüssamet ASLAN
                      Aug 12 '18 at 13:03
















                    27














                    I found easy and elegant DRY solution.



                    It's the snippet:
                    http://djangosnippets.org/snippets/2421/



                    **Placed in templates/includes/tabs.html**

                    <ul class="tab-menu">
                    <li class="{% if active_tab == 'tab1' %} active{% endif %}"><a href="#">Tab 1</a></li>
                    <li class="{% if active_tab == 'tab2' %} active{% endif %}"><a href="#">Tab 2</a></li>
                    <li class="{% if active_tab == 'tab3' %} active{% endif %}"><a href="#">Tab 3</a></li>
                    </ul>

                    **Placed in your page template**

                    {% include "includes/tabs.html" with active_tab='tab1' %}





                    share|improve this answer





















                    • 1





                      How to incorporate this approach if I use {% extends "includes/tabs.html" %} to create desired layouts?

                      – Evgeny Bobkin
                      Jan 3 '18 at 11:41











                    • Why we should include tabs in every page template? It is not DRY solution, I think...

                      – Abdüssamet ASLAN
                      Aug 12 '18 at 13:03














                    27












                    27








                    27







                    I found easy and elegant DRY solution.



                    It's the snippet:
                    http://djangosnippets.org/snippets/2421/



                    **Placed in templates/includes/tabs.html**

                    <ul class="tab-menu">
                    <li class="{% if active_tab == 'tab1' %} active{% endif %}"><a href="#">Tab 1</a></li>
                    <li class="{% if active_tab == 'tab2' %} active{% endif %}"><a href="#">Tab 2</a></li>
                    <li class="{% if active_tab == 'tab3' %} active{% endif %}"><a href="#">Tab 3</a></li>
                    </ul>

                    **Placed in your page template**

                    {% include "includes/tabs.html" with active_tab='tab1' %}





                    share|improve this answer















                    I found easy and elegant DRY solution.



                    It's the snippet:
                    http://djangosnippets.org/snippets/2421/



                    **Placed in templates/includes/tabs.html**

                    <ul class="tab-menu">
                    <li class="{% if active_tab == 'tab1' %} active{% endif %}"><a href="#">Tab 1</a></li>
                    <li class="{% if active_tab == 'tab2' %} active{% endif %}"><a href="#">Tab 2</a></li>
                    <li class="{% if active_tab == 'tab3' %} active{% endif %}"><a href="#">Tab 3</a></li>
                    </ul>

                    **Placed in your page template**

                    {% include "includes/tabs.html" with active_tab='tab1' %}






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited May 31 '17 at 23:27









                    dan-klasson

                    8,77684270




                    8,77684270










                    answered Mar 21 '12 at 9:08









                    sergzachsergzach

                    3,83653265




                    3,83653265








                    • 1





                      How to incorporate this approach if I use {% extends "includes/tabs.html" %} to create desired layouts?

                      – Evgeny Bobkin
                      Jan 3 '18 at 11:41











                    • Why we should include tabs in every page template? It is not DRY solution, I think...

                      – Abdüssamet ASLAN
                      Aug 12 '18 at 13:03














                    • 1





                      How to incorporate this approach if I use {% extends "includes/tabs.html" %} to create desired layouts?

                      – Evgeny Bobkin
                      Jan 3 '18 at 11:41











                    • Why we should include tabs in every page template? It is not DRY solution, I think...

                      – Abdüssamet ASLAN
                      Aug 12 '18 at 13:03








                    1




                    1





                    How to incorporate this approach if I use {% extends "includes/tabs.html" %} to create desired layouts?

                    – Evgeny Bobkin
                    Jan 3 '18 at 11:41





                    How to incorporate this approach if I use {% extends "includes/tabs.html" %} to create desired layouts?

                    – Evgeny Bobkin
                    Jan 3 '18 at 11:41













                    Why we should include tabs in every page template? It is not DRY solution, I think...

                    – Abdüssamet ASLAN
                    Aug 12 '18 at 13:03





                    Why we should include tabs in every page template? It is not DRY solution, I think...

                    – Abdüssamet ASLAN
                    Aug 12 '18 at 13:03











                    4














                    You could make a context variable links with the name, URL and whether it's an active item:



                    {% for name, url, active in links %}
                    {% if active %}
                    <span class='active'>{{ name }}</span>
                    {% else %}
                    <a href='{{ url }}'>{{ name }}</a>
                    {% endif %}
                    {% endfor %}


                    If this menu is present on all pages, you could use a context processor:



                    def menu_links(request):
                    links =
                    # write code here to construct links
                    return { 'links': links }


                    Then, in your settings file, add that function to TEMPLATE_CONTEXT_PROCESSORS as follows: path.to.where.that.function.is.located.menu_links. This means the function menu_links will be called for every template and that means the variable links is available in each template.






                    share|improve this answer


























                    • What do you mean for 3 variables in for loop? for name, url, active. Is this correct to use 3 variables?

                      – sergzach
                      Mar 20 '12 at 19:45













                    • The name is the name of the link (for example, Home), the url is the URL to where the link goes and active is whether the page is currently active. You can compute this for each page and you would get a list of links, such as [("Home", "/home", True), ("Community", "/community", False), ("About", "/about", False)].

                      – Simeon Visser
                      Mar 20 '12 at 19:48






                    • 1





                      It´s indeed possible to use three variables. You can read the documentation of a for loop in Django here: docs.djangoproject.com/en/1.3/ref/templates/builtins/#for (see their example with points).

                      – Simeon Visser
                      Mar 20 '12 at 20:02











                    • This is exactly the solution I came up with. It seems the elegance of python and the power of context processors often goes out the window when it comes to templates, so I like this solution.

                      – andyhasit
                      Jul 2 '17 at 0:37
















                    4














                    You could make a context variable links with the name, URL and whether it's an active item:



                    {% for name, url, active in links %}
                    {% if active %}
                    <span class='active'>{{ name }}</span>
                    {% else %}
                    <a href='{{ url }}'>{{ name }}</a>
                    {% endif %}
                    {% endfor %}


                    If this menu is present on all pages, you could use a context processor:



                    def menu_links(request):
                    links =
                    # write code here to construct links
                    return { 'links': links }


                    Then, in your settings file, add that function to TEMPLATE_CONTEXT_PROCESSORS as follows: path.to.where.that.function.is.located.menu_links. This means the function menu_links will be called for every template and that means the variable links is available in each template.






                    share|improve this answer


























                    • What do you mean for 3 variables in for loop? for name, url, active. Is this correct to use 3 variables?

                      – sergzach
                      Mar 20 '12 at 19:45













                    • The name is the name of the link (for example, Home), the url is the URL to where the link goes and active is whether the page is currently active. You can compute this for each page and you would get a list of links, such as [("Home", "/home", True), ("Community", "/community", False), ("About", "/about", False)].

                      – Simeon Visser
                      Mar 20 '12 at 19:48






                    • 1





                      It´s indeed possible to use three variables. You can read the documentation of a for loop in Django here: docs.djangoproject.com/en/1.3/ref/templates/builtins/#for (see their example with points).

                      – Simeon Visser
                      Mar 20 '12 at 20:02











                    • This is exactly the solution I came up with. It seems the elegance of python and the power of context processors often goes out the window when it comes to templates, so I like this solution.

                      – andyhasit
                      Jul 2 '17 at 0:37














                    4












                    4








                    4







                    You could make a context variable links with the name, URL and whether it's an active item:



                    {% for name, url, active in links %}
                    {% if active %}
                    <span class='active'>{{ name }}</span>
                    {% else %}
                    <a href='{{ url }}'>{{ name }}</a>
                    {% endif %}
                    {% endfor %}


                    If this menu is present on all pages, you could use a context processor:



                    def menu_links(request):
                    links =
                    # write code here to construct links
                    return { 'links': links }


                    Then, in your settings file, add that function to TEMPLATE_CONTEXT_PROCESSORS as follows: path.to.where.that.function.is.located.menu_links. This means the function menu_links will be called for every template and that means the variable links is available in each template.






                    share|improve this answer















                    You could make a context variable links with the name, URL and whether it's an active item:



                    {% for name, url, active in links %}
                    {% if active %}
                    <span class='active'>{{ name }}</span>
                    {% else %}
                    <a href='{{ url }}'>{{ name }}</a>
                    {% endif %}
                    {% endfor %}


                    If this menu is present on all pages, you could use a context processor:



                    def menu_links(request):
                    links =
                    # write code here to construct links
                    return { 'links': links }


                    Then, in your settings file, add that function to TEMPLATE_CONTEXT_PROCESSORS as follows: path.to.where.that.function.is.located.menu_links. This means the function menu_links will be called for every template and that means the variable links is available in each template.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Mar 20 '12 at 19:36

























                    answered Mar 20 '12 at 19:31









                    Simeon VisserSimeon Visser

                    83.1k13127133




                    83.1k13127133













                    • What do you mean for 3 variables in for loop? for name, url, active. Is this correct to use 3 variables?

                      – sergzach
                      Mar 20 '12 at 19:45













                    • The name is the name of the link (for example, Home), the url is the URL to where the link goes and active is whether the page is currently active. You can compute this for each page and you would get a list of links, such as [("Home", "/home", True), ("Community", "/community", False), ("About", "/about", False)].

                      – Simeon Visser
                      Mar 20 '12 at 19:48






                    • 1





                      It´s indeed possible to use three variables. You can read the documentation of a for loop in Django here: docs.djangoproject.com/en/1.3/ref/templates/builtins/#for (see their example with points).

                      – Simeon Visser
                      Mar 20 '12 at 20:02











                    • This is exactly the solution I came up with. It seems the elegance of python and the power of context processors often goes out the window when it comes to templates, so I like this solution.

                      – andyhasit
                      Jul 2 '17 at 0:37



















                    • What do you mean for 3 variables in for loop? for name, url, active. Is this correct to use 3 variables?

                      – sergzach
                      Mar 20 '12 at 19:45













                    • The name is the name of the link (for example, Home), the url is the URL to where the link goes and active is whether the page is currently active. You can compute this for each page and you would get a list of links, such as [("Home", "/home", True), ("Community", "/community", False), ("About", "/about", False)].

                      – Simeon Visser
                      Mar 20 '12 at 19:48






                    • 1





                      It´s indeed possible to use three variables. You can read the documentation of a for loop in Django here: docs.djangoproject.com/en/1.3/ref/templates/builtins/#for (see their example with points).

                      – Simeon Visser
                      Mar 20 '12 at 20:02











                    • This is exactly the solution I came up with. It seems the elegance of python and the power of context processors often goes out the window when it comes to templates, so I like this solution.

                      – andyhasit
                      Jul 2 '17 at 0:37

















                    What do you mean for 3 variables in for loop? for name, url, active. Is this correct to use 3 variables?

                    – sergzach
                    Mar 20 '12 at 19:45







                    What do you mean for 3 variables in for loop? for name, url, active. Is this correct to use 3 variables?

                    – sergzach
                    Mar 20 '12 at 19:45















                    The name is the name of the link (for example, Home), the url is the URL to where the link goes and active is whether the page is currently active. You can compute this for each page and you would get a list of links, such as [("Home", "/home", True), ("Community", "/community", False), ("About", "/about", False)].

                    – Simeon Visser
                    Mar 20 '12 at 19:48





                    The name is the name of the link (for example, Home), the url is the URL to where the link goes and active is whether the page is currently active. You can compute this for each page and you would get a list of links, such as [("Home", "/home", True), ("Community", "/community", False), ("About", "/about", False)].

                    – Simeon Visser
                    Mar 20 '12 at 19:48




                    1




                    1





                    It´s indeed possible to use three variables. You can read the documentation of a for loop in Django here: docs.djangoproject.com/en/1.3/ref/templates/builtins/#for (see their example with points).

                    – Simeon Visser
                    Mar 20 '12 at 20:02





                    It´s indeed possible to use three variables. You can read the documentation of a for loop in Django here: docs.djangoproject.com/en/1.3/ref/templates/builtins/#for (see their example with points).

                    – Simeon Visser
                    Mar 20 '12 at 20:02













                    This is exactly the solution I came up with. It seems the elegance of python and the power of context processors often goes out the window when it comes to templates, so I like this solution.

                    – andyhasit
                    Jul 2 '17 at 0:37





                    This is exactly the solution I came up with. It seems the elegance of python and the power of context processors often goes out the window when it comes to templates, so I like this solution.

                    – andyhasit
                    Jul 2 '17 at 0:37











                    1














                    Assuming the nav item is a link with the same URL as the current page, you could just use JavaScript. Here's an annotated method that I use to add a class="active" to a li in a navigation menu with class="nav":



                    // Get the path name (the part directly after the URL) and append a trailing slash
                    // For example, 'http://www.example.com/subpage1/sub-subpage/'
                    // would become '/subpage1/'
                    var pathName = '/' + window.location.pathname.split('/')[1];
                    if ( pathName != '/' ) { pathName = pathName + '/'; }

                    // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
                    // This returns a top-level nav item
                    var url = window.location.protocol + '//' +
                    window.location.host +
                    pathName;
                    console.log(url);

                    // Add an 'active' class to the navigation list item that contains this url
                    var $links = document.querySelectorAll('.nav a');
                    $link = Array.prototype.filter.call( $links, function(el) {
                    return el.href === url;
                    })[0];
                    $link.parentNode.className += ' active';


                    This method means you can simply pop it into your base template once and forget about it. No repetition, and no manual specification of the page URL in each template.



                    One caveat: this obviously only works if the url found matches a navigation link href. It would additionally be possible to specify a couple of special use cases in the JS, or target a different parent element as needed.



                    Here's a runnable example (keep in mind, snippets run on StackSnippets):






                    // Get the path name (the part directly after the URL) and append a trailing slash
                    // For example, 'http://www.example.com/subpage1/sub-subpage/'
                    // would become '/subpage1/'
                    var pathName = '/' + window.location.pathname.split('/')[1];
                    if ( pathName != '/' ) { pathName = pathName + '/'; }

                    // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
                    // This returns a top-level nav item
                    var url = window.location.protocol + '//' +
                    window.location.host +
                    pathName;
                    console.log(url);

                    // Add an 'active' class to the navigation list item that contains this url
                    var $links = document.querySelectorAll('.nav a');
                    $link = Array.prototype.filter.call( $links, function(el) {
                    return el.href === url;
                    })[0];
                    $link.parentNode.className += ' active';

                    li {
                    display: inline-block;
                    margin: 0 10px;
                    }
                    a {
                    color: black;
                    text-decoration: none;
                    }
                    .active a {
                    color: red;
                    }

                    <ul class="nav">
                    <li>
                    <a href="http://example.com/">Example Link</a>
                    </li>
                    <li>
                    <a href="http://stacksnippets.net/js/">This Snippet</a>
                    </li>
                    <li>
                    <a href="https://google.com/">Google</a>
                    </li>
                    <li>
                    <a href="http://stackoverflow.com/">StackOverflow</a>
                    </li>
                    </ul>








                    share|improve this answer






























                      1














                      Assuming the nav item is a link with the same URL as the current page, you could just use JavaScript. Here's an annotated method that I use to add a class="active" to a li in a navigation menu with class="nav":



                      // Get the path name (the part directly after the URL) and append a trailing slash
                      // For example, 'http://www.example.com/subpage1/sub-subpage/'
                      // would become '/subpage1/'
                      var pathName = '/' + window.location.pathname.split('/')[1];
                      if ( pathName != '/' ) { pathName = pathName + '/'; }

                      // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
                      // This returns a top-level nav item
                      var url = window.location.protocol + '//' +
                      window.location.host +
                      pathName;
                      console.log(url);

                      // Add an 'active' class to the navigation list item that contains this url
                      var $links = document.querySelectorAll('.nav a');
                      $link = Array.prototype.filter.call( $links, function(el) {
                      return el.href === url;
                      })[0];
                      $link.parentNode.className += ' active';


                      This method means you can simply pop it into your base template once and forget about it. No repetition, and no manual specification of the page URL in each template.



                      One caveat: this obviously only works if the url found matches a navigation link href. It would additionally be possible to specify a couple of special use cases in the JS, or target a different parent element as needed.



                      Here's a runnable example (keep in mind, snippets run on StackSnippets):






                      // Get the path name (the part directly after the URL) and append a trailing slash
                      // For example, 'http://www.example.com/subpage1/sub-subpage/'
                      // would become '/subpage1/'
                      var pathName = '/' + window.location.pathname.split('/')[1];
                      if ( pathName != '/' ) { pathName = pathName + '/'; }

                      // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
                      // This returns a top-level nav item
                      var url = window.location.protocol + '//' +
                      window.location.host +
                      pathName;
                      console.log(url);

                      // Add an 'active' class to the navigation list item that contains this url
                      var $links = document.querySelectorAll('.nav a');
                      $link = Array.prototype.filter.call( $links, function(el) {
                      return el.href === url;
                      })[0];
                      $link.parentNode.className += ' active';

                      li {
                      display: inline-block;
                      margin: 0 10px;
                      }
                      a {
                      color: black;
                      text-decoration: none;
                      }
                      .active a {
                      color: red;
                      }

                      <ul class="nav">
                      <li>
                      <a href="http://example.com/">Example Link</a>
                      </li>
                      <li>
                      <a href="http://stacksnippets.net/js/">This Snippet</a>
                      </li>
                      <li>
                      <a href="https://google.com/">Google</a>
                      </li>
                      <li>
                      <a href="http://stackoverflow.com/">StackOverflow</a>
                      </li>
                      </ul>








                      share|improve this answer




























                        1












                        1








                        1







                        Assuming the nav item is a link with the same URL as the current page, you could just use JavaScript. Here's an annotated method that I use to add a class="active" to a li in a navigation menu with class="nav":



                        // Get the path name (the part directly after the URL) and append a trailing slash
                        // For example, 'http://www.example.com/subpage1/sub-subpage/'
                        // would become '/subpage1/'
                        var pathName = '/' + window.location.pathname.split('/')[1];
                        if ( pathName != '/' ) { pathName = pathName + '/'; }

                        // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
                        // This returns a top-level nav item
                        var url = window.location.protocol + '//' +
                        window.location.host +
                        pathName;
                        console.log(url);

                        // Add an 'active' class to the navigation list item that contains this url
                        var $links = document.querySelectorAll('.nav a');
                        $link = Array.prototype.filter.call( $links, function(el) {
                        return el.href === url;
                        })[0];
                        $link.parentNode.className += ' active';


                        This method means you can simply pop it into your base template once and forget about it. No repetition, and no manual specification of the page URL in each template.



                        One caveat: this obviously only works if the url found matches a navigation link href. It would additionally be possible to specify a couple of special use cases in the JS, or target a different parent element as needed.



                        Here's a runnable example (keep in mind, snippets run on StackSnippets):






                        // Get the path name (the part directly after the URL) and append a trailing slash
                        // For example, 'http://www.example.com/subpage1/sub-subpage/'
                        // would become '/subpage1/'
                        var pathName = '/' + window.location.pathname.split('/')[1];
                        if ( pathName != '/' ) { pathName = pathName + '/'; }

                        // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
                        // This returns a top-level nav item
                        var url = window.location.protocol + '//' +
                        window.location.host +
                        pathName;
                        console.log(url);

                        // Add an 'active' class to the navigation list item that contains this url
                        var $links = document.querySelectorAll('.nav a');
                        $link = Array.prototype.filter.call( $links, function(el) {
                        return el.href === url;
                        })[0];
                        $link.parentNode.className += ' active';

                        li {
                        display: inline-block;
                        margin: 0 10px;
                        }
                        a {
                        color: black;
                        text-decoration: none;
                        }
                        .active a {
                        color: red;
                        }

                        <ul class="nav">
                        <li>
                        <a href="http://example.com/">Example Link</a>
                        </li>
                        <li>
                        <a href="http://stacksnippets.net/js/">This Snippet</a>
                        </li>
                        <li>
                        <a href="https://google.com/">Google</a>
                        </li>
                        <li>
                        <a href="http://stackoverflow.com/">StackOverflow</a>
                        </li>
                        </ul>








                        share|improve this answer















                        Assuming the nav item is a link with the same URL as the current page, you could just use JavaScript. Here's an annotated method that I use to add a class="active" to a li in a navigation menu with class="nav":



                        // Get the path name (the part directly after the URL) and append a trailing slash
                        // For example, 'http://www.example.com/subpage1/sub-subpage/'
                        // would become '/subpage1/'
                        var pathName = '/' + window.location.pathname.split('/')[1];
                        if ( pathName != '/' ) { pathName = pathName + '/'; }

                        // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
                        // This returns a top-level nav item
                        var url = window.location.protocol + '//' +
                        window.location.host +
                        pathName;
                        console.log(url);

                        // Add an 'active' class to the navigation list item that contains this url
                        var $links = document.querySelectorAll('.nav a');
                        $link = Array.prototype.filter.call( $links, function(el) {
                        return el.href === url;
                        })[0];
                        $link.parentNode.className += ' active';


                        This method means you can simply pop it into your base template once and forget about it. No repetition, and no manual specification of the page URL in each template.



                        One caveat: this obviously only works if the url found matches a navigation link href. It would additionally be possible to specify a couple of special use cases in the JS, or target a different parent element as needed.



                        Here's a runnable example (keep in mind, snippets run on StackSnippets):






                        // Get the path name (the part directly after the URL) and append a trailing slash
                        // For example, 'http://www.example.com/subpage1/sub-subpage/'
                        // would become '/subpage1/'
                        var pathName = '/' + window.location.pathname.split('/')[1];
                        if ( pathName != '/' ) { pathName = pathName + '/'; }

                        // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
                        // This returns a top-level nav item
                        var url = window.location.protocol + '//' +
                        window.location.host +
                        pathName;
                        console.log(url);

                        // Add an 'active' class to the navigation list item that contains this url
                        var $links = document.querySelectorAll('.nav a');
                        $link = Array.prototype.filter.call( $links, function(el) {
                        return el.href === url;
                        })[0];
                        $link.parentNode.className += ' active';

                        li {
                        display: inline-block;
                        margin: 0 10px;
                        }
                        a {
                        color: black;
                        text-decoration: none;
                        }
                        .active a {
                        color: red;
                        }

                        <ul class="nav">
                        <li>
                        <a href="http://example.com/">Example Link</a>
                        </li>
                        <li>
                        <a href="http://stacksnippets.net/js/">This Snippet</a>
                        </li>
                        <li>
                        <a href="https://google.com/">Google</a>
                        </li>
                        <li>
                        <a href="http://stackoverflow.com/">StackOverflow</a>
                        </li>
                        </ul>








                        // Get the path name (the part directly after the URL) and append a trailing slash
                        // For example, 'http://www.example.com/subpage1/sub-subpage/'
                        // would become '/subpage1/'
                        var pathName = '/' + window.location.pathname.split('/')[1];
                        if ( pathName != '/' ) { pathName = pathName + '/'; }

                        // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
                        // This returns a top-level nav item
                        var url = window.location.protocol + '//' +
                        window.location.host +
                        pathName;
                        console.log(url);

                        // Add an 'active' class to the navigation list item that contains this url
                        var $links = document.querySelectorAll('.nav a');
                        $link = Array.prototype.filter.call( $links, function(el) {
                        return el.href === url;
                        })[0];
                        $link.parentNode.className += ' active';

                        li {
                        display: inline-block;
                        margin: 0 10px;
                        }
                        a {
                        color: black;
                        text-decoration: none;
                        }
                        .active a {
                        color: red;
                        }

                        <ul class="nav">
                        <li>
                        <a href="http://example.com/">Example Link</a>
                        </li>
                        <li>
                        <a href="http://stacksnippets.net/js/">This Snippet</a>
                        </li>
                        <li>
                        <a href="https://google.com/">Google</a>
                        </li>
                        <li>
                        <a href="http://stackoverflow.com/">StackOverflow</a>
                        </li>
                        </ul>





                        // Get the path name (the part directly after the URL) and append a trailing slash
                        // For example, 'http://www.example.com/subpage1/sub-subpage/'
                        // would become '/subpage1/'
                        var pathName = '/' + window.location.pathname.split('/')[1];
                        if ( pathName != '/' ) { pathName = pathName + '/'; }

                        // Form the rest of the URL, so that we now have 'http://www.example.com/subpage1/'
                        // This returns a top-level nav item
                        var url = window.location.protocol + '//' +
                        window.location.host +
                        pathName;
                        console.log(url);

                        // Add an 'active' class to the navigation list item that contains this url
                        var $links = document.querySelectorAll('.nav a');
                        $link = Array.prototype.filter.call( $links, function(el) {
                        return el.href === url;
                        })[0];
                        $link.parentNode.className += ' active';

                        li {
                        display: inline-block;
                        margin: 0 10px;
                        }
                        a {
                        color: black;
                        text-decoration: none;
                        }
                        .active a {
                        color: red;
                        }

                        <ul class="nav">
                        <li>
                        <a href="http://example.com/">Example Link</a>
                        </li>
                        <li>
                        <a href="http://stacksnippets.net/js/">This Snippet</a>
                        </li>
                        <li>
                        <a href="https://google.com/">Google</a>
                        </li>
                        <li>
                        <a href="http://stackoverflow.com/">StackOverflow</a>
                        </li>
                        </ul>






                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Nov 24 '15 at 15:09

























                        answered Dec 19 '14 at 7:49









                        rneviusrnevius

                        21k73764




                        21k73764























                            1














                            Here ist my solution:



                            {% url 'module:list' as list_url %}
                            {% url 'module:create' as create_url %}

                            <ul>
                            <li><a href="{% url 'module:list' %}" class="{% if request.path == list_url %}active{% endif %}">List Page</a></li>
                            <li><a href="{% url 'module:create' %}" class="{% if request.path == create_url %}active{% endif %}">Creation Page</a></li>
                            </ul>





                            share|improve this answer




























                              1














                              Here ist my solution:



                              {% url 'module:list' as list_url %}
                              {% url 'module:create' as create_url %}

                              <ul>
                              <li><a href="{% url 'module:list' %}" class="{% if request.path == list_url %}active{% endif %}">List Page</a></li>
                              <li><a href="{% url 'module:create' %}" class="{% if request.path == create_url %}active{% endif %}">Creation Page</a></li>
                              </ul>





                              share|improve this answer


























                                1












                                1








                                1







                                Here ist my solution:



                                {% url 'module:list' as list_url %}
                                {% url 'module:create' as create_url %}

                                <ul>
                                <li><a href="{% url 'module:list' %}" class="{% if request.path == list_url %}active{% endif %}">List Page</a></li>
                                <li><a href="{% url 'module:create' %}" class="{% if request.path == create_url %}active{% endif %}">Creation Page</a></li>
                                </ul>





                                share|improve this answer













                                Here ist my solution:



                                {% url 'module:list' as list_url %}
                                {% url 'module:create' as create_url %}

                                <ul>
                                <li><a href="{% url 'module:list' %}" class="{% if request.path == list_url %}active{% endif %}">List Page</a></li>
                                <li><a href="{% url 'module:create' %}" class="{% if request.path == create_url %}active{% endif %}">Creation Page</a></li>
                                </ul>






                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Jan 3 at 0:02









                                Tobias ErnstTobias Ernst

                                833811




                                833811























                                    0














                                    Based on @vincent's answer, there is an easier way to do this without messing up with django url patterns.



                                    The current request path can be checked against the rendered menu item path, and if they match then this is the active item.



                                    In the following example I use django-mptt to render the menu but one can replace node.path with each menu item path.



                                    <li class="{% if node.path == request.path %}active{% endif %}">
                                    <a href="node.path">node.title</a>
                                    </li>





                                    share|improve this answer




























                                      0














                                      Based on @vincent's answer, there is an easier way to do this without messing up with django url patterns.



                                      The current request path can be checked against the rendered menu item path, and if they match then this is the active item.



                                      In the following example I use django-mptt to render the menu but one can replace node.path with each menu item path.



                                      <li class="{% if node.path == request.path %}active{% endif %}">
                                      <a href="node.path">node.title</a>
                                      </li>





                                      share|improve this answer


























                                        0












                                        0








                                        0







                                        Based on @vincent's answer, there is an easier way to do this without messing up with django url patterns.



                                        The current request path can be checked against the rendered menu item path, and if they match then this is the active item.



                                        In the following example I use django-mptt to render the menu but one can replace node.path with each menu item path.



                                        <li class="{% if node.path == request.path %}active{% endif %}">
                                        <a href="node.path">node.title</a>
                                        </li>





                                        share|improve this answer













                                        Based on @vincent's answer, there is an easier way to do this without messing up with django url patterns.



                                        The current request path can be checked against the rendered menu item path, and if they match then this is the active item.



                                        In the following example I use django-mptt to render the menu but one can replace node.path with each menu item path.



                                        <li class="{% if node.path == request.path %}active{% endif %}">
                                        <a href="node.path">node.title</a>
                                        </li>






                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Jul 16 '15 at 11:50









                                        WtowerWtower

                                        10.9k97462




                                        10.9k97462























                                            0














                                            I ran into this challenge today with how to dynamically activate a "category" in a sidebar. The categories have slugs which are from the DB.



                                            I solved it by checking to see category slug was in the current path. The slugs are unique (standard practice) so I think this should work without any conflicts.



                                            {% if category.slug in request.path %}active{% endif %}


                                            Full example code of the loop to get the categories and activate the current one.



                                            {% for category in categories %}
                                            <a class="list-group-item {% if category.slug in request.path %}active{% endif %}" href="{% url 'help:category_index' category.slug %}">
                                            <span class="badge">{{ category.article_set.count }}</span>
                                            {{ category.title }}
                                            </a>
                                            {% endfor %}





                                            share|improve this answer
























                                            • I can see this go wrong. For instance, one slug being amazing, and another being amazing_stuff. The unique constraint is satisfied, and yet category.slug in request.path will be true on both pages for amazing.

                                              – Flimm
                                              May 13 '16 at 12:11
















                                            0














                                            I ran into this challenge today with how to dynamically activate a "category" in a sidebar. The categories have slugs which are from the DB.



                                            I solved it by checking to see category slug was in the current path. The slugs are unique (standard practice) so I think this should work without any conflicts.



                                            {% if category.slug in request.path %}active{% endif %}


                                            Full example code of the loop to get the categories and activate the current one.



                                            {% for category in categories %}
                                            <a class="list-group-item {% if category.slug in request.path %}active{% endif %}" href="{% url 'help:category_index' category.slug %}">
                                            <span class="badge">{{ category.article_set.count }}</span>
                                            {{ category.title }}
                                            </a>
                                            {% endfor %}





                                            share|improve this answer
























                                            • I can see this go wrong. For instance, one slug being amazing, and another being amazing_stuff. The unique constraint is satisfied, and yet category.slug in request.path will be true on both pages for amazing.

                                              – Flimm
                                              May 13 '16 at 12:11














                                            0












                                            0








                                            0







                                            I ran into this challenge today with how to dynamically activate a "category" in a sidebar. The categories have slugs which are from the DB.



                                            I solved it by checking to see category slug was in the current path. The slugs are unique (standard practice) so I think this should work without any conflicts.



                                            {% if category.slug in request.path %}active{% endif %}


                                            Full example code of the loop to get the categories and activate the current one.



                                            {% for category in categories %}
                                            <a class="list-group-item {% if category.slug in request.path %}active{% endif %}" href="{% url 'help:category_index' category.slug %}">
                                            <span class="badge">{{ category.article_set.count }}</span>
                                            {{ category.title }}
                                            </a>
                                            {% endfor %}





                                            share|improve this answer













                                            I ran into this challenge today with how to dynamically activate a "category" in a sidebar. The categories have slugs which are from the DB.



                                            I solved it by checking to see category slug was in the current path. The slugs are unique (standard practice) so I think this should work without any conflicts.



                                            {% if category.slug in request.path %}active{% endif %}


                                            Full example code of the loop to get the categories and activate the current one.



                                            {% for category in categories %}
                                            <a class="list-group-item {% if category.slug in request.path %}active{% endif %}" href="{% url 'help:category_index' category.slug %}">
                                            <span class="badge">{{ category.article_set.count }}</span>
                                            {{ category.title }}
                                            </a>
                                            {% endfor %}






                                            share|improve this answer












                                            share|improve this answer



                                            share|improve this answer










                                            answered Feb 6 '16 at 3:29









                                            Alex PhelpsAlex Phelps

                                            1




                                            1













                                            • I can see this go wrong. For instance, one slug being amazing, and another being amazing_stuff. The unique constraint is satisfied, and yet category.slug in request.path will be true on both pages for amazing.

                                              – Flimm
                                              May 13 '16 at 12:11



















                                            • I can see this go wrong. For instance, one slug being amazing, and another being amazing_stuff. The unique constraint is satisfied, and yet category.slug in request.path will be true on both pages for amazing.

                                              – Flimm
                                              May 13 '16 at 12:11

















                                            I can see this go wrong. For instance, one slug being amazing, and another being amazing_stuff. The unique constraint is satisfied, and yet category.slug in request.path will be true on both pages for amazing.

                                            – Flimm
                                            May 13 '16 at 12:11





                                            I can see this go wrong. For instance, one slug being amazing, and another being amazing_stuff. The unique constraint is satisfied, and yet category.slug in request.path will be true on both pages for amazing.

                                            – Flimm
                                            May 13 '16 at 12:11











                                            0














                                            I am using an easier and pure CSS solution. It has its limitations, of which I know and can live with, but it avoids clumsy CSS class selectors, like this:





                                            <a href="index.html" class="item{% if url == request.path %}active{% endif %}">index</a>


                                            Because a space character before active is missing the class selector gets called itemactive instead of item active and this isn't exactly too difficult to get wrong like that.



                                            For me this pure CSS solution works much better:





                                            a.item /* all menu items are of this class */
                                            {
                                            color: black;
                                            text-decoration: none;
                                            }

                                            a.item[href~="{{ request.path }}"] /* just the one which is selected matches */
                                            {
                                            color: red;
                                            text-decoration: underline;
                                            }


                                            Notice: This even works if the URL has additional path components, because then href also matches partially. That could eventually cause 'collisions' with more than one match, but often enough it just works, because on well structured websites a "subdirectory" of an URL usually is a child of the selected menu item.






                                            share|improve this answer




























                                              0














                                              I am using an easier and pure CSS solution. It has its limitations, of which I know and can live with, but it avoids clumsy CSS class selectors, like this:





                                              <a href="index.html" class="item{% if url == request.path %}active{% endif %}">index</a>


                                              Because a space character before active is missing the class selector gets called itemactive instead of item active and this isn't exactly too difficult to get wrong like that.



                                              For me this pure CSS solution works much better:





                                              a.item /* all menu items are of this class */
                                              {
                                              color: black;
                                              text-decoration: none;
                                              }

                                              a.item[href~="{{ request.path }}"] /* just the one which is selected matches */
                                              {
                                              color: red;
                                              text-decoration: underline;
                                              }


                                              Notice: This even works if the URL has additional path components, because then href also matches partially. That could eventually cause 'collisions' with more than one match, but often enough it just works, because on well structured websites a "subdirectory" of an URL usually is a child of the selected menu item.






                                              share|improve this answer


























                                                0












                                                0








                                                0







                                                I am using an easier and pure CSS solution. It has its limitations, of which I know and can live with, but it avoids clumsy CSS class selectors, like this:





                                                <a href="index.html" class="item{% if url == request.path %}active{% endif %}">index</a>


                                                Because a space character before active is missing the class selector gets called itemactive instead of item active and this isn't exactly too difficult to get wrong like that.



                                                For me this pure CSS solution works much better:





                                                a.item /* all menu items are of this class */
                                                {
                                                color: black;
                                                text-decoration: none;
                                                }

                                                a.item[href~="{{ request.path }}"] /* just the one which is selected matches */
                                                {
                                                color: red;
                                                text-decoration: underline;
                                                }


                                                Notice: This even works if the URL has additional path components, because then href also matches partially. That could eventually cause 'collisions' with more than one match, but often enough it just works, because on well structured websites a "subdirectory" of an URL usually is a child of the selected menu item.






                                                share|improve this answer













                                                I am using an easier and pure CSS solution. It has its limitations, of which I know and can live with, but it avoids clumsy CSS class selectors, like this:





                                                <a href="index.html" class="item{% if url == request.path %}active{% endif %}">index</a>


                                                Because a space character before active is missing the class selector gets called itemactive instead of item active and this isn't exactly too difficult to get wrong like that.



                                                For me this pure CSS solution works much better:





                                                a.item /* all menu items are of this class */
                                                {
                                                color: black;
                                                text-decoration: none;
                                                }

                                                a.item[href~="{{ request.path }}"] /* just the one which is selected matches */
                                                {
                                                color: red;
                                                text-decoration: underline;
                                                }


                                                Notice: This even works if the URL has additional path components, because then href also matches partially. That could eventually cause 'collisions' with more than one match, but often enough it just works, because on well structured websites a "subdirectory" of an URL usually is a child of the selected menu item.







                                                share|improve this answer












                                                share|improve this answer



                                                share|improve this answer










                                                answered Oct 21 '16 at 1:20









                                                MaxCMaxC

                                                9616




                                                9616























                                                    0














                                                    I have come up with a way to utilize block tags within menu-containing parent template to achieve something like this.



                                                    base.html - the parent template:



                                                    <a href="/" class="{% block menu_home_class %}{% endblock %}">Home</a>
                                                    <a href="/about" class="{% block menu_about_class %}{% endblock %}">About</a>
                                                    <a href="/contact" class="{% block menu_contact_class %}{% endblock %}">Contact</a>

                                                    {% block content %}{% endblock %}


                                                    about.html - template for a specific page:



                                                    {% extends "base.html" %}

                                                    {% block menu_about_class %}active{% endblock %}

                                                    {% block content %}
                                                    About page content...
                                                    {% endblock %}


                                                    As you can see, the thing that varies between different page templates is the name of the block containing active. contact.html would make use of menu_contact_class, and so on.



                                                    One benefit of this approach is that you can have multiple subpages with the same active menu item. For example, an about page might have subpages giving information about each team members of a company. It could make sense to have the About menu item stay active for each of these subpages.






                                                    share|improve this answer




























                                                      0














                                                      I have come up with a way to utilize block tags within menu-containing parent template to achieve something like this.



                                                      base.html - the parent template:



                                                      <a href="/" class="{% block menu_home_class %}{% endblock %}">Home</a>
                                                      <a href="/about" class="{% block menu_about_class %}{% endblock %}">About</a>
                                                      <a href="/contact" class="{% block menu_contact_class %}{% endblock %}">Contact</a>

                                                      {% block content %}{% endblock %}


                                                      about.html - template for a specific page:



                                                      {% extends "base.html" %}

                                                      {% block menu_about_class %}active{% endblock %}

                                                      {% block content %}
                                                      About page content...
                                                      {% endblock %}


                                                      As you can see, the thing that varies between different page templates is the name of the block containing active. contact.html would make use of menu_contact_class, and so on.



                                                      One benefit of this approach is that you can have multiple subpages with the same active menu item. For example, an about page might have subpages giving information about each team members of a company. It could make sense to have the About menu item stay active for each of these subpages.






                                                      share|improve this answer


























                                                        0












                                                        0








                                                        0







                                                        I have come up with a way to utilize block tags within menu-containing parent template to achieve something like this.



                                                        base.html - the parent template:



                                                        <a href="/" class="{% block menu_home_class %}{% endblock %}">Home</a>
                                                        <a href="/about" class="{% block menu_about_class %}{% endblock %}">About</a>
                                                        <a href="/contact" class="{% block menu_contact_class %}{% endblock %}">Contact</a>

                                                        {% block content %}{% endblock %}


                                                        about.html - template for a specific page:



                                                        {% extends "base.html" %}

                                                        {% block menu_about_class %}active{% endblock %}

                                                        {% block content %}
                                                        About page content...
                                                        {% endblock %}


                                                        As you can see, the thing that varies between different page templates is the name of the block containing active. contact.html would make use of menu_contact_class, and so on.



                                                        One benefit of this approach is that you can have multiple subpages with the same active menu item. For example, an about page might have subpages giving information about each team members of a company. It could make sense to have the About menu item stay active for each of these subpages.






                                                        share|improve this answer













                                                        I have come up with a way to utilize block tags within menu-containing parent template to achieve something like this.



                                                        base.html - the parent template:



                                                        <a href="/" class="{% block menu_home_class %}{% endblock %}">Home</a>
                                                        <a href="/about" class="{% block menu_about_class %}{% endblock %}">About</a>
                                                        <a href="/contact" class="{% block menu_contact_class %}{% endblock %}">Contact</a>

                                                        {% block content %}{% endblock %}


                                                        about.html - template for a specific page:



                                                        {% extends "base.html" %}

                                                        {% block menu_about_class %}active{% endblock %}

                                                        {% block content %}
                                                        About page content...
                                                        {% endblock %}


                                                        As you can see, the thing that varies between different page templates is the name of the block containing active. contact.html would make use of menu_contact_class, and so on.



                                                        One benefit of this approach is that you can have multiple subpages with the same active menu item. For example, an about page might have subpages giving information about each team members of a company. It could make sense to have the About menu item stay active for each of these subpages.







                                                        share|improve this answer












                                                        share|improve this answer



                                                        share|improve this answer










                                                        answered Jan 25 '18 at 11:15









                                                        Magnus TeekiviMagnus Teekivi

                                                        183417




                                                        183417






























                                                            draft saved

                                                            draft discarded




















































                                                            Thanks for contributing an answer to Stack Overflow!


                                                            • Please be sure to answer the question. Provide details and share your research!

                                                            But avoid



                                                            • Asking for help, clarification, or responding to other answers.

                                                            • Making statements based on opinion; back them up with references or personal experience.


                                                            To learn more, see our tips on writing great answers.




                                                            draft saved


                                                            draft discarded














                                                            StackExchange.ready(
                                                            function () {
                                                            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9793576%2fhow-to-render-menu-with-one-active-item-with-dry%23new-answer', 'question_page');
                                                            }
                                                            );

                                                            Post as a guest















                                                            Required, but never shown





















































                                                            Required, but never shown














                                                            Required, but never shown












                                                            Required, but never shown







                                                            Required, but never shown

































                                                            Required, but never shown














                                                            Required, but never shown












                                                            Required, but never shown







                                                            Required, but never shown







                                                            Popular posts from this blog

                                                            MongoDB - Not Authorized To Execute Command

                                                            How to fix TextFormField cause rebuild widget in Flutter

                                                            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith