0

I'm trying to stylise my navigation menu regarding selected page.

I made a page for news, but when I click on the following pages (page 2 for example), the navigation menu loses its class. I want it retains its current-item-menu class on this case.

How can I do this ?

Thanks for your help !

2 Answers 2

0

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:

2
  • I did not think it would be so complex to achieve this. Why are you saying that This may not be the best way to get the current URL ? But anyway, it worked for me, thank you :)
    – Meivyn
    Commented Feb 17, 2016 at 0:57
  • I just meant there may be a better way, I'm not sure, the SO question I linked to talks about some issues with IPv6 for example and you could probably ignore the port part. It's always worked for me anyway :)
    – Cai
    Commented Feb 17, 2016 at 1:18
0

Iam not sure that I fully understand your question, but maybe you can try something like this.

See this Image:

some simple wp menu

You see that the current active page is "Child".

The pages "Child" and "Another Child" are childpages of the page "Parent". With that I mean I selected the "Parent" page under "Page Attributes" in the backend.

Than I created a menu, but just added these 3 sites in a row on the same level(not hirachical), as you can see on the image.

Remember the current active page is "Child", but you can see that the "Parent" menu-item has a special class to it:

current-page-parent

This class is added because I selected the parent on the "Page Attributes".

To test this I just did the following: I changed the "Child" page to be no longer a child of the "Parent" page. (I selected no parent)

Than I had to re-save the menu / re-add the menu item(Child), and after that the current-page-parent class was gone! (the class stays if you dont update the menu, atleast on my testsite this was the case!)

So maybe try and add some styling to the current-page-parent class, or fiddle around with it. You could add the same styling as you have for your current item.

You will see that also other classes will be added to every item, like an ancestor class for example.

Have a good day!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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