Programmatically Adding a Menu Item to a WordPress Menu

Just today I had to add a logo to a WordPress menu on a site I was working on. Because it is a graphic that I needed to add, I couldn’t easily use the default WordPress menu functionality to accomplish this. One possible workaround, I think, could have been to add a class to the menu item. Then, I could use CSS to add an image and hide the text. In this particular case, though, the logo I was adding was the last menu item so there was a much easier option available to me.

Fortunately, WordPress offers a filter, wp_nav_menu_items, to change the content of a WordPress menu. The filter has two arguments, the menu items as a string, and an array of arguments. Here is an example of how I would call my own function, scc_add_logo_to_footer_menu using this filter:

add_action( 'wp_nav_menu_items', 'scc_add_logo_to_footer_menu', 10, 2 );

And here is the code for my function:

function scc_add_logo_to_footer_menu( $items, $args ) {
    if( $args->theme_location != 'footer_menu' ) {
        return $items;
    }
    $mma_link  = '<li id="footer-logo" class="menu-item nav-item"><a href="https://example.edu/" target="_blank">';
    $mma_link .= '<img src="' . get_stylesheet_directory_uri() . '/images/footer-logo.png" alt="Logo"/>';
    $mma_link .= '</a></li>';
    $items .= $mma_link;
    return $items;
}

The first thing we need to do is to target the correct menu. The wp_nav_menu_items filter is going to be run for every menu you are displaying on your site. The second parameter in our function, $args, is an array that contains a lot of useful information about the menu currently being processed. I personally used Ray to see what was available to me in the $args array and here is an example of what I got:

The information available in the $args array

I figured that the item least likely to change was the theme_location so that was what I looked at in my function. First and foremost, if my theme_location wasn’t “primary,” I knew that I was not on the menu I wanted. So, I simply return the menu’s original items and stop right there:

if( $args->theme_location != 'footer_menu' ) {
    return $items;
}

When you are bailing with a return in a filter, remember to return the original information sent to the function. I know certain programmers who have done just a return instead of return $items in the past which leads to there being no menu items being displayed. Ahem.

Once determined we have the right menu we can add our own item to the menu items. The $items is just a string so I created the link I wanted as $mma_link and then appended it to the $items. Pretty straightforward! If I was looking to add a new item in the middle of the menu, that would be much tougher. Because $items is a string, we would need to figure out a way to split the string, add our item, and put the pieces back together. And, since the menu can be changed by a user, it is very possible that you wouldn’t know where in the list you needed to add your own item or what to look for. For appending or prepending a menu item, though, the wp_nav_menu_items filter offers an easy way to accomplish this.

Leave a comment

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