1

When defining the menu item, I can only choose a unique URL for language. But I want that a bunch of pages, one of them the referenced by the menu item, highlight that menu item (Products) so I know I am in that section of the page. For example:

www.example.com/products
www.example.com/search-product
www.example.com/product-detail

all would have to highlight the menu-item := products, that which references the first URL above.

I have tried with the following code but I am not sure if there is a faster and more direct approach, it seems too convoluted to me to theme() nothing to keep the above desired effect

Code:

   print theme('links__system_main_menu', array(
        'links' => $main_menu,
        'attributes' => array(

        ),
        'heading' => array(
          'text' => t('Main menu'),
          'level' => 'h2',

        ),
      ));  


function theme_links__system_main_menu($variables) {
  $html = "<ul>";  
  foreach ($variables['links'] as $link) {


  // HERE I would change $link['href'] to merge the 3 links
  //together and make that this item is hilited when I am in one of the 3  
  //links. Of course, the href link will direct to the first one, but
  //the hilite will make the user to know that she is in this section.


    $html .= "<li>".l($link['title'], $link['href'], $link)."</li>";
  }
  $html .= "  </ul>";
  $html .= "";

   return $html;
}

Another coded approach:

 $a = menu_tree_output( menu_tree_page_data("main-menu") );
 print "<ul>";
foreach($a as $key => $value){
 active = "";
   if($value["#href"] == current_path() || ( drupal_is_front_page() && $value["#href"] == "<front>" ) ){
     // HERE I would change $link['href'] to merge the 3 links
    //together and make that this item is hilited when I am in one of the 3  
    //links. Of course, the href link will direct to the first one, but
    //the hilite will make the user to know that she is in this section.


    $active = 'class="active"';
   }
        if($value["#href"] == "<front>"){
            $url = "";
        }else{
            $url = drupal_get_path_alias($value["#href"]);
        } // if
        if($value["#title"] != "") print '<li><a ' . $active . ' href="' . $base_url . "/" . $language->language . "/" . $url . '">' . $value["#title"] . "</a></li>";
    } // foreach
     print "</ul>";   
1

Recently I've the same needs in my site and the fastest and painless approach was doing in CSS instead create preprocess functions.

This was done in Drupal 8, but works independently of what you are using.

First make sure that you have a class or id named with your path in any place of your HTML, and then, just use it to style your link with same 'active' class. Something like this...

HTML:

<body class="path-product-detail">
  <header>
    <nav class="main-menu">
      <ul>
        <li><a href="/home">Home</a></li>
        <li><a href="/products">Products</a></li>
        <li><a href="/contact">Contact</a></li>
      </ul>
    <nav>
  </header>
  ...
</body>

CSS:

.main-menu .active, 
.path-product-detail .main-menu a[href="/products"] {
  color: #fff;
  background-color: #c9093e;
}

Try in JSFiddle:
https://jsfiddle.net/t4vny2df/1/

Edit 1: Detailed explanation
First of all, in your html.tpl.php template make sure that the current path is printed as a class, this will be dynamically specified, all the magic is right here in this class (in Drupal 7, by default, seems the class is page-'currentPath' according docs).

Your HTML must print current path in body element.

<body class="page-currentPath ...">
...
</body>

Now, based in this class just use the right CSS selectors to highlight the menu item. I'm going to use the 'products' html code example.

.main-menu /*Note 1*/ .active /*Note 2*/, 
.page-product-detail /*Note 3*/ .main-menu a[href="/products"] /*Note 4*/, 
.page-search-product /*Note 5*/ .main-menu a[href="/products"] /*Note 4*/{
  color: #fff;
  background-color: #c9093e;
}

First, in CSS we can use a combination of selectors do get the right element and we can use 'comma' to specify another selector to the same style (a, p{color: #000} /*Element 'a' and element 'p' will be color black*/)

Note 1 - Considering your menu with a class 'main-menu'.
Note 2 - Considering that you are using a 'active' class for current path.
Note 3 - If body has a class 'page-product-detail' this selector will be considered.
Note 4 - This selector will get the menu item that you want highlight and doesn't have a 'active' class, because you are not in '/products' page.
Note 5 - If body has a class 'page-search-product' this selector will be considered.

For more pages just add another line with your 'page selector'. Any questions just leave a comment and I explain.

  • Sorry, but I do not see how this solves the problem. I have just tested and it highlights the item "products". But I need to highlight in function of the URL, and even have 2, 3 or more different URLs which highlight the same item. I do not see your approach doing that. – Cesar Feb 10 '16 at 15:24
  • Hmm, lets see if I understood. You have a bunch of URL ('/products', '/search-product', '/product-detail') and all of them highlight the same menu item ('/products') right? If yes, my approach resolve this. Just add CSS selectors to cover all cases. My answer is not a copy/paste solution, sry for that, I just demonstrate how you can archive what you asked, you need adequate for your case. – Vagner Feb 10 '16 at 16:52
  • Sorry, I cannot understand your code. I do not see how it can work, and when tested, I have a URL .../this-is-an-url, and still the item products is highlighted in your example. You must provide a working example of autodetection of URL and highlighting the corresponding item menu, when you have an array of values for the URLs of a given item menu. I will be happy with a working example with just 2 different URLs for Product and one URL for News, for example. – Cesar Feb 11 '16 at 7:18
  • Now I understand. This is a very clever approach. The dynamical part of page-currentPath is what was missing. Thank you very much for so detailed explanation, now it is crystal-clear. – Cesar Feb 11 '16 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.