Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
Source Link
Cai
  • 613
  • 5
  • 16

You can use the nav_menu_css_class filter to alter the classes added to navigation items. You need to check the current menu items URL against the URL of the page you are on.

add_filter( 'nav_menu_css_class', 'wpse_217882_menu_class', 10, 2 );
function wpse_217882_menu_class( $classes = array(), $item = false ) {

    // Get current URL
    $current_url = wpse_217882_current_url();

    // Get homepage URL
    $homepage_url = trailingslashit( get_bloginfo( 'url' ) );

    // Don't do anything on 404s or the homepage
    if( is_404() || $item->url == $homepage_url || $item->url == '/' )
        return $classes;

    // Check if the current URL contains the items URL
    // This should match paginated pages for example
    if ( strstr( $current_url, $item->url ) ) {
        // Add the '.current-menu-item' class
        $classes[] = 'current-menu-item';
    }

    // You can use this to match different URLs
    // This will add the .current-menu-item class to the /blog/ nav item
    // when viewing /category/ pages
    if ( strstr( $item->url, '/blog/' ) && strstr( $current_url, '/category/' ) ) {
        // Add the '.current-menu-item' class
        $classes[] = 'current-menu-item';
    }

    return $classes;
}

This is the function to get the current URL used in the wpse_217882_menu_class function. It uses the global $_SERVER to build the URL.

function wpse_217882_current_url() {

    // Protocol
    $url = ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ) ? 'https://' : 'http://';
    // Server
    $url .= $_SERVER['SERVER_NAME'];
    // Port
    $url .= ( '80' == $_SERVER['SERVER_PORT'] ) ? '' : ':' . $_SERVER['SERVER_PORT'];
    // URI
    $url .= $_SERVER['REQUEST_URI'];

    return trailingslashit( $url );
}

This may not be the best way to get the current URL but I have used this in the past. You can read more about getting the current URL here: