6

Is it possible to limit maximum menu depth in admin panel /nav-menus.php?

I need this because my theme won't support more than two levels of menu, so there is no point in allowing a user to make deeper menus.

3

Follow up on @jmarceli's and @squarecandy's great answers. Here is a solution that allows for:

  • Easier scaling (set an object in the php action)
  • Updates to the correct menu depth when the location checkboxes are changed
/**
 * Limit max menu depth in admin panel 
 */

function limit_admin_menu_depth($hook)
{
    if ($hook != 'nav-menus.php') return;

    wp_register_script('limit-admin-menu-depth', get_stylesheet_directory_uri() . '/js/admin/limit-menu-depth.js', array(), '1.0.0', true);
    wp_localize_script(
        'limit-admin-menu-depth',
        'myMenuDepths',
        array(
            'primary' => 1, // <-- Set your menu location and max depth here
            'footer' => 0 // <-- Add as many as you like
        )
    );
    wp_enqueue_script('limit-admin-menu-depth');
}
add_action( 'admin_enqueue_scripts', 'limit_admin_menu_depth' );

js

/**
 * Limit max menu depth in admin panel
 * Expects wp_localize_script to have set an object of menu locations
 * in the shape of { location: maxDepth, location2: maxDepth2 }
 * e.g var menu-depths = {"primary":"1","footer":"0"};
 */
(function ($) {
    // Get initial maximum menu depth, so that we may restore to it later.
    var initialMaxDepth = wpNavMenu.options.globalMaxDepth;

    function setMaxDepth() {
        // Loop through each of the menu locations
        $.each(myMenuDepths, function (location, maxDepth) {
            if (
                $('#locations-' + location).prop('checked') &&
                maxDepth < wpNavMenu.options.globalMaxDepth
            ) {
                // If this menu location is checked
                // and if the max depth for this location is less than the current globalMaxDepth
                // Then set globalMaxDepth to the max depth for this location
                wpNavMenu.options.globalMaxDepth = maxDepth;
            }
        });
    }

    // Run the function once on document ready
    setMaxDepth();

    // Re-run the function if the menu location checkboxes are changed
    $('.menu-theme-locations input').on('change', function () {
        wpNavMenu.options.globalMaxDepth = initialMaxDepth;
        setMaxDepth();
    });
})(jQuery);

2
  • 1
    This is a wonderful solution/improvement. This is why I love Stack Exchange — over time, answers just keep getting better. Thanks for sharing! Just gotta upvote this so people see it sooner. – dkeeling Dec 1 '20 at 23:14
  • Hi buddy. Great that the solution has helped you. And, yes indeed, I too value the sharing and iteration of ideas here. ✌️ – Davey Dec 8 '20 at 14:35
10

The solution that I came up with:

/**
 * Limit max menu depth in admin panel to 2
 */
function q242068_limit_depth( $hook ) {
  if ( $hook != 'nav-menus.php' ) return;

  // override default value right after 'nav-menu' JS
  wp_add_inline_script( 'nav-menu', 'wpNavMenu.options.globalMaxDepth = 1;', 'after' );
}
add_action( 'admin_enqueue_scripts', 'q242068_limit_depth' );
1

Follow up on @jmarceli's great answer to target specific menu locations

function squarecandy_menu_admin_limit_depth( $hook ) {
  if ( 'nav-menus.php' !== $hook ) {
    return;
  }

  wp_enqueue_script( 'squarecandy-admin-menu-depth', get_stylesheet_directory_uri() . '/js/admin-menu-depth.js', array(), '1.0.0', true );
}
add_action( 'admin_enqueue_scripts', 'squarecandy_menu_admin_limit_depth' );

js

// Force Menu Depth to Match Front End

// main menu can only have one child level
if ( document.getElementById("locations-main-menu").checked ) {
    wpNavMenu.options.globalMaxDepth = 1;
}

// footer menu have only top level
if ( document.getElementById("locations-footer-menu").checked ) {
    wpNavMenu.options.globalMaxDepth = 0;
}

// all other menu locations stay at the WP default
2
  • Nice solition, ty. I noticed a minor mistake: get_stylesheet_directory() should be get_stylesheet_directory_uri(). Hope you don't mind but I made a few improvements, see my answer in case you're interested. – Davey Oct 23 '20 at 8:46
  • 1
    Good call, thanks @Davey. I edited it. – squarecandy Oct 28 '20 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.