Add Items in Menu with wp_nav_menu_filter

wp_nav_menu_filter allows you add items at the end of a menu in WordPress but what about adding an item at the start of a menu or in a specific place.

add_filter( 'wp_nav_menu_items', 'prefix_add_menu_item', 10, 2 );
/**
 * Add Menu Item to end of menu
 */
function prefix_add_menu_item ( $items, $args ) {
   if( $args->theme_location == 'primary' )
       $items .=  '<li class="menu-item">...</li>';
      } 
       return $items;
}

So here a custom menu item is added to the menu in the primary location, if you don’t have menu locations you can target the menu directly by altering the filter name to include the menu ID – let’s say the menu ID is menu-primary-menu you would just use primary-menu like so…

add_filter( 'wp_nav_menu_primary-menu_items', 'prefix_add_menu_item', 10, 2 );
/**
 * Add Menu Item to end of menu
 */
function prefix_add_menu_item ( $items, $args ) {
       $items .=  '<li class="menu-item">...</li>';

       return $items;
}

Get your underscores and dashes right.

Add menu items at the start of a menu with wp_nav_menu_items

Change the position of the $items parameter and return a new parameter $new_items that includes the new menu item $start_menu_item followed by the existing menu items $items

add_filter( 'wp_nav_menu_primary-menu_items', 'prefix_add_menu_item', 10, 2 );
/**
 * Add Menu Item to end of menu
 */
function prefix_add_menu_item ( $items, $args ) {
       $start_menu_item =  '<li class="menu-item">...</li>';
       $new_items = $start_menu_item . $items;

       return $new_items;
}

Adding a custom item to a specific place in the menu

Works only on single level menu, so will fail with submenus.

add_filter( 'wp_nav_menu_primary-menu_items', 'prefix_add_menu_item', 10, 2 );
/**
 * Add Menu Item to a specific place in the menu
 */
function prefix_add_menu_item ( $items, $args ) {
        
$items_array = array();
        while ( false !== ( $item_pos = strpos ( $items, '<li', 10 ) ) ) // Add the position where the menu item is placed
        {
            $items_array[] = substr($items, 0, $item_pos);
            $items = substr($items, $item_pos);
        }
        $items_array[] = $items;
        array_splice($items_array, 9, 0, '<li class="menu-item">...</li>'); // insert custom item after 9th item one

        $items = implode('', $items_array);
       
       return $items;
}

So in the code above the custom item is inserted as the 10th item, there are 2 instances in the code where the position needs to be inserted as commented in the code.

The menu is effectively split into 2 and the custom item is appended after the first then the second part of the menu is appended after that.

Example:

Add Search Toggle Icon at End of Menu in WordPress

add_filter( 'wp_nav_menu_items', 'prefix_add_menu_item', 10, 2 );
/**
 * Add Menu Item to end of menu
 */
function prefix_add_menu_item ( $items, $args ) {
   if( $args->theme_location == 'main-menu' ){
       $items .= '<li class="search search-wpb"><a class="search-icon"><i class="fa fa-search"></i></a><div style="display:none;" class="wpbsearchform">'. get_search_form(false) .'</div></li>';
        
      } 
       return $items;
}

jQuery slideToggle to Reveal Search Form

jQuery(document).ready(function($){
/* Search Menu */
 $(".search-icon").click(function() {
	$(".wpbsearchform").slideToggle();
});

$(document).keyup(function(e) {
// Ref https://stackoverflow.com/questions/3369593/how-to-detect-escape-key-press-with-pure-js-or-jquery
		// Close search if esc key pressed
		if (e.key == "Escape") {
		  $(".wpbsearchform").hide();
		}
	});
});

As well as the search form be set to slideToggle on click, a second function will dismiss the search form if the ESC key is clicked.

CSS

li.search.search-wpb{    position: relative;
}
.wpbsearchform {
    position: absolute;
    right: 0px;
    top: 100%;
    width: 260px;
    z-index: 2;
}

Modify the Search Form’s Content

You may want to modify the search forms content such as the placeholder text, this is possible with the get_search_form filter.

<?php 
add_filter( 'get_search_form', 'wpb_alter_search_form', 20 );
	// Modify Search Form
	function wpb_alter_search_form( $form ){
	    return '<form role="search" method="get" id="searchform" action="' . esc_url( home_url( '/' ) ) . '" >
	    <input type="search"  name="s"  placeholder="SEARCH..." value/>
	    </form>';
}

Thank wpbeaches.com

Leave a Reply

Your email address will not be published. Required fields are marked *