• metalhead

    (@aaronthomas1979)


    I’ve added a function which adds a menu item (Mail) to my nav menu. I did this because I couldn’t figure out a way to do it via the GUI.

    While the menu item works, I’m unable to get it to acquire the current class. The menu item doesn’t change it’s appearance when it’s active/current.

    // Adds Mail with counter to header menu
    function my_nav_menu_positioned_msgs_counter( $menu, $args ) {
    
    $msg_url = bp_core_get_user_domain(bp_loggedin_user_id()) .'messages/';
    $user=wp_get_current_user();
    $name=$user->display_name;
    if (!is_user_logged_in())
            return $menu;
        else
    $int = bp_get_total_unread_messages_count();
        if( $args->theme_location == 'Header Menu' ) // only for primary menu
        {
            $menu_array = array();
            while ( false !== ( $item_pos = strpos ( $menu, '<li', 3) ) )
            {
                $menu_array[] = substr($menu, 0, $item_pos);
                $menu = substr($menu, $item_pos);
            }
            $menu_array[] = $menu;
            array_splice($menu_array, 3, 0, '<li><a href=" ' .$msg_url. ' " title="Read or compose private messages"><p style="font-weight:bold;">Mail <span class="badge">'.bp_get_total_unread_messages_count( bp_loggedin_user_id()).'</span></p></a></li>'); // 0,0 is first position, 1,0 is second, etc
    
            $menu = implode('', $menu_array);
        }
        return $menu;
    }
    add_filter('wp_nav_menu_items','my_nav_menu_positioned_msgs_counter', 10, 2);

    Is there a simple fix for this? I’ve read other similar posts, but I couldn’t find anything that worked for my situation.

Viewing 6 replies - 1 through 6 (of 6 total)
  • Moderator bcworkz

    (@bcworkz)

    You did right. There’s no way to create dynamic menu items from the GUI. Your code needs to determine what the current request is. If the request is for the message page this item leads to, simply add the correct class to the other classes. You can likely determine the requested item with get_queried_object_id().

    Hi Do you want to highlight the current menu item ?

    Thread Starter metalhead

    (@aaronthomas1979)

    Thank you to both of you for the replies. Yes, I’m trying to get the menu item called “Mail” to remain highlighted while active.

    I read about get_queried_object_id() on a few forums, but I couldn’t understand how it works. Here’s an example of what I found:

    function get_queried_object_id() {
      global $wp_query;
      return $wp_query->get_queried_object_id();
    }

    My assumption is that this is a core function, and I can run it, but how will I use it in this case?

    I’m guessing that the code I’m lacking would work something like this:

    (First, I’d set up a class for “Mail” and call it MailClass, then I’d do this:)

    if ($wp_query->get_queried_object_is() !== current)
    <script>
    $(".MailClass").attr('class', 'current');
    </script>

    Am I way off? I’ll try this in the meantime, but my chances of being right about this are slim. ??

    Moderator bcworkz

    (@bcworkz)

    I can see you had the right idea, but it’s backwards and more convoluted than necessary. If you use the PHP class method, you’ll need to declare the object global, just like the procedural function does. Or stick with the procedural function. I’m assuming your message page has an ID, and you want to add a HTML class attribute so the menu item can be displayed differently when the message page is the current page, as sumithsuku11 was asking. Maybe you want to make it appear disabled instead of highlighted, that is a CSS rule either way, the assigned class wouldn’t need to change.

    You would be modifying the menu item as it is declared in PHP, so there is no need for jQuery script to alter the class unless you are swapping pages via Ajax, in which case the handling is entirely different. I’m not sure where you want the attribute to appear, lets say it’s the li tag and the message page ID is 123. You could then do something like the following at the array_splice line of your my_nav_menu_positioned_msgs_counter function:

    $class = 123 == get_queried_object_id() ? ' class="current"' : '';
    array_splice( $menu_array, 3, 0, '<li' . $class . '><a href=" //... and the rest of the line';
    Thread Starter metalhead

    (@aaronthomas1979)

    Thanks for this advice.

    One (hopefully) small setback to this is that this message page isn’t actually a page. Will that be a problem? It has a url, like this: /site/username/messages

    Is there a way to refer to the url instead of the page ID?

    I apologize for being so illiterate about all this, and I appreciate your patience.

    Moderator bcworkz

    (@bcworkz)

    No worries! You’re trying to learn this stuff, that is commendable. Not being a page isn’t a huge problem. What does the URL actually return? If it’s another object besides a page, getting the queried ID may still work. You can also use get_queried_object() to get the entire query. There will be something within that object that will confirm it’s a messages request.

    And yes, checking the requested URL should also work, as long as there were no redirects that confuse the issue. You can check if $_SERVER['REQUEST_URI'] has the correct value. The terminal slash may not be there, and any URL parameters will be included, so using strpos() instead of equivalence will be preferable. Checking $_SERVER['REDIRECT_URL'] may sometimes be a better option. If there are no redirects, it’ll have the same URL as REQUEST_URI, but the URL parameters are stripped.

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘wp_nav_menu_items and current class’ is closed to new replies.