Filtering WordPress menu items

Recently I had a request come in to update the navigation on a WordPress site.
The way the request was worded made me think the change to the menu needed to happen on one specific page, and not across the entire site.

This created an interesting problem, as the theme only appeared to support a
single menu. Also, it didn’t help that the menu system, which I think may be
baked into WordPress) didn’t support any sort of copy feature, without the need for third party plugins.

None of this was going to stop me, so my next step was to learn a bit about the
functions that WordPress provides that would allow me to mung with the menu items before displaying said menu.

Fortunately, there is the filter_wp_nav_menu_objects() function that does exactly what it says, it allows you to filter the navigation menu’s objects.

Since I only wanted this to be applied to one page, I started by interrogating
the $post->page_name to limit the scope of when the logic would be applied.

From there, I looped through the menu items, and for my particular scenario, I
checked the URL and omitted the item I wanted to remove from the menu.

Putting it all together, it looks something like this, which will need to be
added before where you’re calling wp_nav_menu():

<?php
// Only apply to a particular page
if ($post->postname === 'some-page') {
    function filter_wp_nav_menu_objects($menu_items, $args) {
        // This is where we'll store the menu items we do want to display
        $next_menu_items = [];

        foreach ($menu_items as $menu_item) {
            // This is where you'll want to add any filtering logic. For me, I
            // set it up to skip over pages that match a particular URL
            if (strpos($menu_item->url, '/some-page') !== false) {
                continue;
            }

            $next_menu_items[] = $menu_item;
        }

        return $next_menu_items;
    }

    add_filter('wp_nav_menu_objects', 'filter_wp_nav_menu_objects', 10, 2);
}

wp_nav_menu($main_navbar_args);
PHP

Definitely a hack job, but there’s really not much to it!

Sadly, after putting in the time to figure this all out, I found out that the requirement was to update the menu on all pages, and not just a particular one.

While I certainly did more work than I had to, it’s always nice to learn something new. Never know when this will be something I need to figure out in
the future.

Josh Sherman - The Man, The Myth, The Avatar

About Josh

Husband. Father. Pug dad. Musician. Founder of Holiday API, Head of Engineering and Emoji Specialist at Mailshake, and author of the best damn Lorem Ipsum Library for PHP.


If you found this article helpful, please consider buying me a coffee.