WordPress.org

Forums

[resolved] Large Number of Custom Menu Items not Saving (5 posts)

  1. jamesguy9
    Member
    Posted 2 years ago #

    Hello,

    I am having an issue when trying to save a custom menu (/wp-admin/nav-menus.php) and it takes 5-6 minutes to process, upon which it gives me a 404 Error afterwards. I've done a number of things to try and remedy this:

    1. Deactivate all plugins and the theme.
    2. Increase values within my php.ini file (max_execution_time = 300, max_input_time = 200, post_max_size = 100 etc.).
    3. Search various topics on Google.

    But have had no luck. Has anyone else encountered this and found a solution? The menu has 100+ items.

    Please let me know if you have any questions & thanks very much in advance.

  2. esmi
    Forum Moderator
    Posted 2 years ago #

    Sounds like you're hitting a custom menu limitation issue.
    http://core.trac.wordpress.org/ticket/14134

  3. jamesguy9
    Member
    Posted 2 years ago #

    Thanks esmi,

    I'm trying to determine the fix from that ticket. There is a hack which is referenced, but where should it be included?

    I also noticed that there is a related fix posted in that ticket: http://core.trac.wordpress.org/ticket/22070

    There is a long bit of code on that page starting with "jQuery(function($) {", where should this be placed? From its description, it should solve my issue.

    Thanks.

  4. esmi
    Forum Moderator
    Posted 2 years ago #

    You would need to enqueue the hack mentioned in http://core.trac.wordpress.org/ticket/22070 but, ultimately, this is always going to be a server-related issue. Frankly, I cannot understand why anyone would want a custom menu with 100+ items. It goes against all usability recommendations.

  5. jamesguy9
    Member
    Posted 2 years ago #

    I found the solution!

    I used the code from here: http://core.trac.wordpress.org/ticket/22070

    I made the first fix the poster recommended and then I added the following code to line 468 of nav-menus.php:

    <script type="text/javascript">
    jQuery(function($) {
      // the currently displayed menu form
      var $form = $('#update-nav-menu');
    
      // Listen to new menus, since we have no possibility to hook
      // we have to interval it, because we can't capture an event here
      $('.submit-add-to-menu').click(function() {
        var $item_count = $form.find('.menu-item-handle').length;
        var $interval_id = setInterval(function() {
          var $current_item_count = $form.find('.menu-item-handle').length;
          if ($item_count < $current_item_count) {
            clearInterval($interval_id);
            // Add the dirty flag and set it to dirty immediately
            add_dirty_flags(1);
            // Reassign the mousedown/up events
            assign_mouse_events();
          }
        },200);
      });
    
      // add a hidden field, telling if the menu is dirty (by default, it's not)
      function add_dirty_flags($flag) {
        $form.find('.menu-item-handle').each(function() {
          if ($(this).find('.dirty-handle').length == 0) {
            var $html = '<input type="hidden" class="dirty-handle" value="' + $flag + '" />';
            $(this).append($html);
            console.log('flag added');
          }
        });
      }
    
      // (re)assigns mouse events to menu items
      function assign_mouse_events() {
        var $menu_items = $('.menu-item-bar');
        // Unbind previously assigned events
        $menu_items.unbind('mouseup').unbind('mousedown');
    
        // Dirty Flag handler if a click happens
        $menu_items.mousedown(function() {
          $(this).find('.dirty-handle').val('1');
        });
    
        // if the parent changes on release the mouse handle, change all items with the new parent to dirty
        $menu_items.mouseup(function() {
          menu_save_mouseup($(this));
        });
      }
    
      // The call back for mouseup on menu bars
      function menu_save_mouseup($this) {
        var $temp_object = $this.parent();
        // Mark everything with the same parent dirty
        setTimeout(function() {
          var $parent_id = $temp_object.find('.menu-item-data-parent-id').val();
          // Go through all fields, dirtying everything that has the same parent
          $('.menu-item-data-parent-id').each(function() {
            if ($(this).val() == $parent_id)
              $(this).parent().prev().find('.dirty-handle').val('1');
          });
        },200);
      }
    
      // On submit make every undirty menu an empty title, so it won't get saved
      // We're using a hoax in nav-menus.php, line 335 here..
      $form.submit(function() {
        // Now traverse all handles and make only dirties saveable
        $form.find('.menu-item-handle').each(function() {
          // Find the dirty flag
          var $is_dirty = $(this).find('.dirty-handle').val();
          $(this).find('.dirty-handle').remove();
          if ($is_dirty == 0) {
            // The div containing the menu informations
            var $forms = $(this).parent().next();
            // Remove the title value so it doesn't get saved
            $forms.find('.edit-menu-item-title').val('');
          }
        });
        return true;
      });
    
      // Assign mouse events on first load
      assign_mouse_events();
      // Add all dirty flags (not dirty by default of course)
      add_dirty_flags(0);
    });
    </script>

    This makes the menu actually save and do so quickly.

    It's a very large site which, unfortunately, requires many nav items.

    Thanks again for your help.

Topic Closed

This topic has been closed to new replies.

About this Topic