How do I override the default way Wordpress' determines the .current-menu-item class?


Tags: php,css,wordpress,wordpress-plugin,bbpress

Problem :

Lots of people, both here on SOW and elsewhere, are having my same exact problem.

I've installed the BBpress plugin on my site here. This plugin enables a FORUM on the site.

I've wrestled for days (to no avail) on this documented issue where the plugin causes the wrong menu item to be highlighted when any Forum sub-menu item is chosen. Instead, the Blog menu item gets highlighted by default.

Check it out: Click on Forum and this resulting page highlights the "Forum" menu item okay. But click on "Test forum" (or drill down into any other Forum item) and the resulting page always has "Blog" highlighted.

Here's what I know so far:

  • It can't be fixed with CSS alone.
  • I am using Permalinks (with "Post name" selected)
  • PHP assigns a .current-menu-item and/or a .current_page_item class (along with their corresponding -ancestor and -parent classes) to menu items based on the page you've navigated to. For some reason, it is failing to see any Forum submenu as a current page. As a result, it is defaulting to "Blog" as the current page item.
  • So I know I need to do the following:
    1. have Wordpress check the URL upon each page load
    2. if "/forums/" is part of the URL, remove all .current-menu* and .current_page* classes (the wildcard is necessary to purge the ancestor/parent classes).
    3. then assign .current-menu-item and .current_page_item classes to the "Forum" menu item.

The problem is, while I think i'm getting close, I don't know how - exactly - to do this.

I've tried a bunch of things.

I found this Jquery solution but don't know how to implement it, nor am I confident in this approach:

// First add a “forum-class” to your forums menu item in your custom menu 
// Then add this to your js file with YOURURL = the url of your site and forums = your forums slug : 

$(function() { 
    var forumURL = window.location.href.indexOf("YOURURL/forums/");
    if(forumURL > -1){
        $('li.forum-class').addClass('current-menu-item');
    }   
});

Then, I found this approach which seemed closer to what I wanted, but it introduces a new class and doesn't seem to clear the incorrect classes from the Blog menu. Plus, I don't know where exactly to put this code, or where to create the js file.

if (strtolower($thats_all->post_title) == "forum" || strtolower($thats_all->post_title) == "forums") {
    $addclass = ' class="current_page"';
} else {
    $addclass = '';
}

Finally, I found this which is what I think I need, but I'm having trouble implementing it (I've tried sticking it in my menu-primary.php and header.php but no go).

// this forces the class current-menu-item to a menu item which I named 'forums' 

add_filter('nav_menu_css_class', 'remove_link_parent_menu_classes', 420 ,3);
function remove_link_parent_menu_classes($classes, $item, $args){

if(strpos($item->url, '/forums/') !== true)
    return array_diff($classes, array('current_page_item', 'current-menu-item'));

return $classes;
}

I think I'm close. Really close. Just need a push in the right direction. I need to know:

  • will the latter solution above work?
  • which file, and where exactly in the file, do I need to place the code?

Thanks!



Solution :

I finally cracked it! Using the above clues, I figured out this code that worked for me.

add_filter( 'nav_menu_css_class', 'namespace_menu_classes', 10, 2 );
function namespace_menu_classes( $classes , $item ){
    if ( get_post_type() == 'forum' ) {
        $classes = str_replace( 'current_page_parent', '', $classes );
        $classes = str_replace( 'menu-item-16', 'current_page_parent', $classes );
    }
    return $classes;
}

Copy the above at the end of the function.php file.

Then change 'forum' to the slug name you've chosen and replace 'menu-item-16' with the correctly numbered menu item that you want highlighted (you will need to use your web browser's developer tools to inspect your site to be able to find this).

This took me a week to figure out (and learn the php required)! Good luck and hope this helps everyone else out there.


    CSS Howto..

    How can I fix the menu on the implanted header?

    How to flatten checkbox using CSS? [duplicate]

    How am I supposed to change the Bootstrap CSS properties in a new Yeoman project?

    How to select html5 range's pseudo-elements in JavaScript

    I need a max-margin CSS property, but it doesn't exist. How could I fake it?

    How to fill larger image into smaller div?

    How to create a shadow in HTML, CSS & JS that doesn't accept clicks, but let it hit behind that layer?

    How align div to a form field?

    How to dynamically change width of Div1 inside a scrollable Div2 to Div2's width

    In CSS/SVG, how to rotate each character of a word?

    How do I push inline elements onto the next line

    How to change the attribute value of an element with by another element Selector in HTML + CSS?

    How to create push button?

    CSS How to multiple background + gradient?

    How do I hover with text over div img?

    CSS: How to fake a :hover state?

    Ambiguous match, found 2 elements matching css, how to get to the second one?

    How to stop columns wrapping in three column liquid page?

    How to prevent javascript and css messing up?

    How to disable selection with specific class with js/css?

    CSS: How to set several div's in one line with 100% width?

    How to hide :before in overflow:hidden element

    How to fix side bar and header using CSS for JS & jQuery Scroller

    HTML code to show splitted data_frame in one html page using python

    How to increase the duration of :active in css?

    How do I get a CSS class to work in my Javascript file?

    how to apply jquery ui/css to forum field

    How to style first paragraph

    of the content differently without using css class , ID or javascript, with IE6 compatibility?

    How to use bootstrap to hide one of div when zoom browser windows size smaller

    How do I correctly locate a div within a list when making a horizontal nav bar with HTML/CSS?