I have a custom menu using the new Menu System but it is not returning in the correct order. I have no idea what order its in – its not alphabetical, or by date, or by any pattern I can see.

The link is http://www.oia.co.za/.

The pages “sponsors”, “archives” and “fewtchafests” are supposed to appear as the last 3 items, after the series of numbers, not before them. If the first item wasn’t also a number, I might think it was rendering all numbers last, but that first item (“8333”) kind of scuppers that idea.

Screenshot of correctly dragged-and-dropped menu order attached, screenshot of website displaying wrong order attached, and the code used to call the menu is below.

correct menu order

enter image description here

    <!-- BEGIN ADVENT CALENDAR -->
    <nav role="navigation">
        <?php 
            wp_nav_menu( array(
                'theme_location' => 'advent-calendar',
                'menu' => 'advent-calendar',
                'menu_class' => 'component-calendar',
                'container_id' => 'calendar',
                'container_class' => 'advent',
                'orderby' => 'menu_order',
                'walker'=> new Salamander_Advent_Walker()
                ) 
            );
        ?>
    </nav>
    <!-- END ADVENT CALENDAR -->

EDIT: It’s definitely a problem with my custom walker (code below) – if I comment out the call to the custom walker function, it generates in the right order:

    class Salamander_Advent_Walker extends Walker_page {
        function start_el(&$output, $item, $depth, $args) {
           private $color_idx = 1;

            $advent_thumbnail = get_post_meta($item->object_id, 'advent-thumb', true);
            $advent_slug = get_post_meta($item->object_id, 'advent-slug', true);
            $advent_oneliner = get_post_meta($item->object_id, 'advent-oneliner', true);
            $advent_color = get_post_meta($item->object_id, 'advent-color', true);
            $advent_small_title = get_post_meta($item->object_id, 'advent-title', true);

            $advent_title = ( !empty($advent_small_title) ? $advent_small_title : $advent_slug);

            $output .= $indent . '
                        <li class="color'.$this->color_idx.' active">
                        <a href="#day'. $advent_slug .'">
                            <span class="day">
                                <strong>'. $advent_slug .'</strong>
                                <span>&nbsp;</span>
                            </span>
                            <span class="content">
                                <small class="'. $advent_color .'">'. $advent_title .'</small>
                                <img src="'. $advent_thumbnail .'" width="126" height="91" alt="advent" />
                                <strong>'. $advent_oneliner .'</strong>
                            </span>
                        </a>
                    ';
            $this->color_idx++;
            if ($this->color_idx > 4) {
                $this->color_idx = 1;
            }
        } // ends function
    } // ends class

1 Answer
1

AFAIK there’s a non-documented orderby parameter, that can be set to menu_order.

Edit: Straight from core, inside /wp-includes/nav-menu-template.php Line# 195 (WP 3.3.1):

$sorted_menu_items = array();
foreach ( (array) $menu_items as $key => $menu_item )
    $sorted_menu_items[$menu_item->menu_order] = $menu_item;

It’s the lines immediately before the Walker runs. So the set menu_order should affect the order. You’ll just have to set it inside your page from the meta box.

In short: You shouldn’t need a custom Walker at all.

Sidnotes:

  • You don’t have to use that $indent. It make really no sense as it’s only for the source code.
  • You don’t have to make it that hard to save your meta data into single vars. Also would this add lots of queries if they’re currently not cached. Do it the following way:

    extract( get_post_custom( $item->object_id ), EXTR_SKIP );
    

Edit: extract simply makes single variables out of your custom meta data. The key is then the new name of your variable. EXTR_SKIP cares about making the variables unique as it skips double keys.

// Example: Structure of your post custom/meta data
Array( 
    [0] => array( 'example_key_name' => array( 'example_value' ) )
    [1] => array( 'another_key_name' => 'another_value' )
)
// Becomes:
$example_key_name = array( 0 => 'example_value' );
// Value can now be called as:
$example_key_name[0];
// Becomes:
$another_key_name="another_value";
// Value can be called as:
$another_key_name

The last example is not really possible, as you normally got serialized arrays as custom values (even for single values). So you’ll always have to append [0] to your variable. But this technique def. shortens code. Especially if you got really large sets of meta data per post/CPT.

Tags:

Leave a Reply

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