Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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
share|improve this question
    
Do you have a custom menu defined AND assigned to this theme_location, or is the output being generated by the fallback? –  Chip Bennett Mar 9 '12 at 15:48
    
@ChipBennett Yes, custom menu defined and location assigned. –  Amanda Mar 20 '12 at 11:24
4  
okay, next step: remove the custom walker argument, and verify whether the menu renders properly or not. If it does, then the problem is your custom walker. –  Chip Bennett Mar 20 '12 at 13:02
1  
:) Yes, it's definitely the walker (and you have me thinking "Why didn't I think of that myself?") –  Amanda Mar 20 '12 at 14:10
add comment

1 Answer

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.

share|improve this answer
    
Thanks - I've included the orderby parameter, but it didn't change anything. Thanks for the note about $indent (I do like my source-code to look neat, but that's just because I'm anal). How do I use the extract() function, or rather, how do I assign variables like $advent_thumbnail etc for use later if I use extract()? –  Amanda Mar 20 '12 at 11:32
    
@Amanda See (both) edits. –  kaiser Mar 20 '12 at 16:02
    
@Amanda Still following? –  kaiser Mar 26 '12 at 20:25
    
Hi - thanks, I understand the extract now... regarding not needing a custom walker - I had thought that would be the easiest way to retrieve a bunch of custom meta for display? "You'll just have to set it inside your page from the meta box." My home page isn't actually a "page", so there is no custom meta box to set menu order - the site is set to display "Latest Posts" in the settings, and this odd front page is managed by home.php. –  Amanda Mar 26 '12 at 21:18
1  
Could you go into core, and add echo '<pre>'; print_r($sorted_menu_items); echo '</pre>'; right below the lines I quoted from core ↑, then reload the page and post the result here? Thanks. –  kaiser Mar 27 '12 at 11:00
show 4 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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