21

I'm Twitter Bootstrap and need to add data-toggle="modal" attribute to the a tag of menu link. Upon searching most all results reference doing a walking for Twitter Bootstrap dropdown menus however this menu has no dropdowns and I only need to add the particular attribute.

Next I found this: Add custom attributes to menu items without plugin which is very helpful as it appears in WordPress 3.6+ we no longer have to do long complex walkers and instead can use this: http://codex.wordpress.org/Plugin_API/Filter_Reference/nav_menu_link_attributes

However as of this running that API reference is quite bare and offers no examples and since it's so new there are very few references to it on Google.

I tried this first:

add_filter( 'nav_menu_link_attributes', 'mywp_contact_menu_atts', 10, 3 );

function pb_contact_menu_atts( $atts, $item, $args )
{
    // inspect $item, then …
    $atts['data-toggle'] = 'modal';
    return $atts;
}

and that does work however it as expected adds the attribute to all the a tags in the menu. So I'm trying to figure out how to target one menu item with #menu-item-7857 a or such.

Does anyone know where to find an example of targeting a menu item or able to determine how to basd on the information that's in the above linked API reference?

To note, I did find the following one example but it only targets items that have children which does not help but may be in the right direction:

add_filter('nav_menu_link_attributes', function($atts, $item, $args) {
    if ( $args->has_children )
    {
        $atts['data-toggle'] = 'dropdown';
        $atts['class'] = 'dropdown-toggle';
    }

    return $atts;
}, 10, 3);

UPDATE - The only answer below sounds like it's on to something but from it wasn't able to determine how to actually find the number to target my specific link and where/how to add that conditional in a working example. Added a comment but didn't hear back. Since been about 18 days thought I'd see if a bounty would help.

When I look at the code for the link I want to target:

<li id="menu-item-7858" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-7858"><a href="#" data-toggle="modal">Chat</a></li>

I see the number 7858 so thinking maybe that is the number I should be targeting.

But when I try for instance:

add_filter( 'nav_menu_link_attributes', 'my_chat_menu_atts', 10, 3 );


function my_chat_menu_atts( $atts, $item, $args ) {
    if ( 7857 == $item['ID'] ) {
        // inspect $item, then …
        $atts['onclick'] = 'SnapEngage.startLink();';
        return $atts;
    }
}

However adding that if statement the one commenter suggested I get the following error:

Fatal error: Cannot use object of type WP_Post as array

I'm assuming more code is required but at a lost. As a reminder without the if statement it works however it targets all links rather than the one link I want to target.

1
  • I want to insert <?php the_id();?> into the $atts variable.something like that // inspect $item if ($item->ID == $menu_target) { $atts['data-toggle'] = 'modal-<?php the_id();?>'; } return $atts; Can u please help me how can i insert the_id into the $atts variable. Thanks
    – nadzhq
    Feb 15, 2014 at 6:42

4 Answers 4

41
+50

Specifically editing the code you provided in the original question:

add_filter( 'nav_menu_link_attributes', 'wpse121123_contact_menu_atts', 10, 3 );
function wpse121123_contact_menu_atts( $atts, $item, $args )
{
  // The ID of the target menu item
  $menu_target = 123;

  // inspect $item
  if ($item->ID == $menu_target) {
    $atts['data-toggle'] = 'modal';
  }
  return $atts;
}
5
  • After I swapped in some of my own values that did it! Thank you! Marked it as correct, but says I need to wait 23 more hours before I can award the bounty. Nov 22, 2013 at 15:50
  • Happy to help! :D
    – Jen
    Nov 22, 2013 at 15:51
  • I set a reminder in Fantastical so I don't forget to award the bounty tomorrow. Nov 22, 2013 at 16:07
  • What if you have several menu items as target? Nov 20, 2015 at 12:23
  • just use multiple if statement if data-toggle value is different. Or you can save id into array key (considering they are unique) and modal name as array value. Then check the if statement with array_key_exists()
    – Sisir
    Apr 17, 2016 at 13:32
8

The second $item argument, which is being made available to your filter function, contains a menu item object. If dumped it looks something like this:

[1] => WP_Post Object
    (
        [ID] => 2220
        [post_author] => 1
        [post_date] => 2012-12-26 19:29:44
        [post_date_gmt] => 2012-12-26 17:29:44
        [post_content] => 
        [post_title] => Home
        [post_excerpt] => 
        [post_status] => publish
        [comment_status] => open
        [ping_status] => open
        [post_password] => 
        [post_name] => home-3
        [to_ping] => 
        [pinged] => 
        [post_modified] => 2013-06-05 01:55:20
        [post_modified_gmt] => 2013-06-04 22:55:20
        [post_content_filtered] => 
        [post_parent] => 0
        [guid] => http://dev.rarst.net/?p=2220
        [menu_order] => 1
        [post_type] => nav_menu_item
        [post_mime_type] => 
        [comment_count] => 0
        [filter] => raw
        [db_id] => 2220
        [menu_item_parent] => 0
        [object_id] => 2220
        [object] => custom
        [type] => custom
        [type_label] => Custom
        [title] => Home
        [url] => http://dev.rarst.net/
        [target] => 
        [attr_title] => 
        [description] => 
        [classes] => Array
            (
                [0] => 
                [1] => menu-item
                [2] => menu-item-type-custom
                [3] => menu-item-object-custom
                [4] => current-menu-item
                [5] => current_page_item
                [6] => menu-item-home
            )

        [xfn] => 
        [current] => 1
        [current_item_ancestor] => 
        [current_item_parent] => 
    )

To target specific menu item you need to formulate your condition and check it against data available in the object, for example if ( 2220 == $item['ID'] )

2
  • Thanks for this! I'm not quite sure I understand how to get the $item ID for my particular menu item however. In your example the 2220 is also the same as your url "dev.rarst.net/?p=2220". My link I want to add the data-attribute to doesn't go to another wordpress url but rather is href="#ContactForm". Based on your example above I googled more and tried running echo var_export($GLOBALS['post'], TRUE); but when I look near the invidual menu item I don't see any unique ID. Can you clarify? Or in "if ( 2220 == $item['ID'] )" Thanks in advance! Nov 4, 2013 at 14:07
  • 2
    The error you're seeing is because $item is an object, not an array; change the $item['ID'] to $item->ID.
    – Jen
    Nov 22, 2013 at 15:36
1

Why don't you approach this problem from a different direction? Rather than attempting to target the menu item with id == ?? which could change at some point (the menu item, not the id), use the WP Admin area to add a custom class to the menu item you want to target. Then use that class in your Javascript to trigger the information you need:

$('.my-class').click(function(e){
  // do other stuff
  e.preventDefault;
});

My javascript is not guaranteed. If you're not using jQuery, you could try this.

1

I wanted to add data-letters to the custom menu that I had created in WordPress.

The steps I chose was:

  1. Found my menu's id number.
  2. added those lines of code from @guiniveretoo
  3. wrote if statements for each menu items (as I wanted different attribute values to be injected.)
  4. worked!

Here is my code.

add_filter( 'nav_menu_link_attributes', 'wpse121123_contact_menu_atts', 10, 3 );
function wpse121123_contact_menu_atts( $atts, $item, $args )
{  
  $menu_target = 6;

  if ($item->ID == $menu_target) {
    $atts['data-letters'] = 'PROJECTS';
  }

  elseif ($item->ID == 7) {
    $atts['data-letters'] = 'RESUME';
  }
  elseif ($item->ID == 8) {
    $atts['data-letters'] = 'ARTWORKS';
  }
  elseif ($item->ID == 9) {
    $atts['data-letters'] = 'HELLO!';
  }
  return $atts;
}

Hope this helps you.

Your Answer

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

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