Wordpress - How make top level menu item not have link, but have sub-menus that are linked?

The easiest way to do it without a plugin or anything is to use the "Menus" function of WordPress. Here are the instructions for WordPress 4.8:

  1. From your WordPress dashboard, go to "Appearance -> Menus"
  2. In the "Edit Menus" tab, select "Custom Links"
  3. For the URL, Enter "#" (no quotes)
  4. For the link text, enter your desired text for the top level of your drop-down menu
  5. Click the "Add to Menu" button
  6. Drag the menu item to its desired position within your menu
  7. For the menu item you just added, click the down arrow to the right of the item (it will read "custom link" to the left of the item)
  8. Remove the "#" from the URL. This - in all browsers - will convert the link to plain text.
  9. Click on the "Save Menu" button

I have a few ideas:

  1. Set the custom link to # which won't return anything
  2. Add a custom class to the items and then use jQuery to remove the links.
  3. Use a PHP equivalent to the jQuery method
  4. Use the Disable Parent Menu Link plugin (or take it apart and write your own)

The simplest method I came up with was to create a Custom Link item with the Link URL value of #. This is sending the user to an empty hash on the same page, so basically links nowhere.

However, there are some side-effects of using empty hashes for placeholder links. The link will still appear and behave like a link, so it could confuse a user when they are clicking on what appears to be a link but nothing happens. The other effect is that clicking on an empty hash link will override any existing hash, sending the user to the top of the page. This might not be so worrying for a menu which is at the top of the page anyway, but it is quite jarring when the page unexpectedly jumps when you are not expecting it, especially if this is for a footer menu.

The solution is to combine the empty hash method with a piece of code to detect when empty hash links are used in the menu and to remove the href attribute from that link entirely. An a element without a href attribute is the correct HTML 5 method of creating an placeholder link.

/**
 * Remove the href from empty links `<a href="#">` in the nav menus
 * @param string $menu the current menu HTML
 * @return string the modified menu HTML
 */
add_filter( 'wp_nav_menu_items', function ( $menu ) {
    return str_replace( '<a href="#"', '<a', $menu );
} );

Tags:

Menus