Remove menu link types from the WordPress menu options screen

On a client site, we wanted to restrict menu items to Custom Links, only. Thus remove all other menu types. The main drive behind this was to improve the user experience and reduce confusion, as the menu is only for Social Links.

With a brief search yielding very little I set about coding a solution, by hooking into the admin_head action. But before we get into the code, let’s review what we need to do.

Scenario: Only display Custom Links

WordPress admin menus screen with only custom links as the available link type

When the current screen is the Menu screen and the selected menu is social_navigation, conditionally remove all link types except Custom Links. To do this we need to:
– get the current screen
– get the currently selected menu
– check if the current menu is the social_navigation menu
– get a list of all link types
– remove all links that aren’t Custom Links

Get the current screen

This one’s easy, we append -nav-menu.php to the add_action hook:

add_action('admin_head-nav-menus.php' ...);

Now, the action will only fire when we’re on the menu screen of the admin area.

Get the currently selected menu

Though, not a straightforward as above, we can get this form the globally scoped variables, in the form of the menu’s id:

global $nav_menu_selected_id;

Next we’ll use this to check if the current menu is social_navigation.

Check if the current menu is the Social Menu

This is a little fiddly, as we need to compare the id from $nav_menu_selected_id with the id of the Social Menu. So first, lets get a list of available menus, then we can compare their id‘s with $nav_menu_selected_id. For this I’ll grab another global variable:

global $menu_locations;

Then compare the id of social_navigation with $nav_menu_selected_id to see if we’re currently viewing the Social Menu.

Get a list of all link types

Another global variable comes to the rescue here, $wp_meta_boxes. This is a multidimensional array of all meta-boxes, including the nav-menus. So everything we need is in $wp_meta_boxes['nav-menus']['side'] (we only need side as all nav-menu meta-boxes are of side context):

global $wp_meta_boxes;
// $wp_meta_boxes['nav-menus']['side'] holds all the nav-menus

Remove all links that aren’t Custom Links

All we need to do is loop through the $wp_meta_boxes['nav-menus']['side'] array and conditionally remove the link type if its id doesn’t match add-custom-links:

foreach ($wp_meta_boxes['nav-menus']['side'] as $nav_menus) {
    foreach ($nav_menus as $nav_id => $nav_menu) {
        if ($nav_id !== 'add-custom-links') {
            remove_meta_box($nav_id, 'nav-menus', 'side');
        }
    }
}

And that’s it. Here’s the full code, copy an paste this into your functions.php file, or better still, a functionality plugin, modify it to suit your needs and you’re good to go:

/**
 * Remove nav menu meta-box links from the 'social_navigation' menu
 *
 * NB:  all nav menus are $context 'side'
 *
 *      use var_dump(wp_list_pluck($nav_menus,'id'))
 *      inside the outer loop to display a list of all link type IDs
 */
function custom_remove() {
    global $wp_meta_boxes, $nav_menu_selected_id, $menu_locations;

    // store the id of the social menu
    $social_nav = $menu_locations['social_navigation'] ?? false;

    // if the current menu id is the social menu's then let's do this
    if ($social_nav === $nav_menu_selected_id) {

        // loop through the 'core' and 'default' arrays 
        foreach ($wp_meta_boxes['nav-menus']['side'] as $nav_menus) {

            // loops through their menus
            foreach ($nav_menus as $nav_id => $nav_menu) {

                // remove the menu's meta-box if it isn't the one we want to keep
                if ($nav_id !== 'add-custom-links') {
                    remove_meta_box($nav_id, 'nav-menus', 'side');
                }
            }
        }
    }
}
add_action('admin_head-nav-menus.php', __NAMESPACE__.'\\custom_remove', 10);

Note: We namespace our environment for conflict avoidance, hence the __NAMESPACE__ prepended function call.

Conclusion

This is a really nice bit of code for improving the user experience and keeping control of your menus. I especially like it because it’s pretty lightweight, too!

If you have any questions, or have a particular programming challenge, especially with WordPress, please get in touch and we’ll gladly help, as we’re seasoned in WP – designing and building custom themes and plugins. And love a challenge.