1

If I want to sort on 1) menu_order and if the pages weight the same I want to 2) sort them alphabetically, how? Is this the default behavior if you set menu_order?

Is it?:

$args = array(
    'sort_order' => 'ASC',
    'sort_column' => 'menu_order, post_title'
);
$children = get_pages($args);

Or?:

$args = array(
    'sort_order' => 'ASC',
    'sort_column' => 'menu_order post_title'
);

Or?:

$args = array(
    'sort_order' => 'ASC',
    'sort_column' => 'menu_order | post_title'
);

Or?:

$args = array(
    'sort_order' => 'ASC',
    'sort_column' => array('menu_order', 'post_title')
);

etc...

From wp_query it seems like it would be a simple space? Multiple orderby values in WP_Query

Should really be in the spec.!

2 Answers 2

4

get_pages explodes sort_column on the comma (,) character. Just check the source:

foreach ( explode( ',', $sort_column ) as $orderby ) {

So the correct format should be the first one you posted:

$args = array(
    'sort_order' => 'ASC',
    'sort_column' => 'menu_order, post_title'
);
$children = get_pages($args);

If you are not seeing the ordering you expect it is probably because of how the ASC is applied. The ASC sort order is going to be applied to the last item in the list, not to all of them.

3755            $query = "SELECT * FROM $wpdb->posts $join WHERE ($where_post_type) $where ";
3756            $query .= $author_query;
3757            $query .= " ORDER BY " . $sort_column . " " . $sort_order ;

That ASC is tacked onto the SQL after the complete ORDER BY statement resulting in something like this: ORDER BY menu_order, post_title ASC. I suspect that you want ORDER BY menu_order ASC, post_title or ORDER BY menu_order ASC, post_title ASC instead.

To get either of those results, you will need to use WP_Query because the SQL used by get_pages is pretty rigid and not easily filtered as it uses $wpdb->get_results directly.

You will still need a filter, though, as WP_Query handles order the same way that get_pages does.

function alter_order_wpse_115183($orderby) {
  remove_action('posts_orderby','alter_order_wpse_115183');
  $pattern = '([^ ]+) (ASC|DESC)$';
  preg_match('/'.$pattern.'/',$orderby,$matches);
  if (empty($matches[2])) {
    return $orderby;
  }
  if (!empty($matches[1])) {
    $order = str_replace(',',' '.$matches[2].',',$matches[1]).' '.$matches[2];
    // or
    // $order = str_replace(',',' '.$matches[2].',',$matches[1]);
  }
  return $order;
}
add_action(
  'posts_orderby',
  'alter_order_wpse_115183'
);
$args = array(
  'post_type' => 'page',
    'order' => 'ASC',
    'orderby' => 'menu_order title'
);
$children = new WP_Query($args);
var_dump($children->request);

$children = new WP_Query($args);
var_dump($children->request); die;
1
  • Thanks for the correct answer! I just wanted to point out that MySQL Default sort order, when using ORDER BY, is ascending and that's what I wanted anyway but it's good to know how it works and how you would solve it otherwise also. Thanks! dev.mysql.com/doc/refman/5.0/en/sorting-rows.html
    – OZZIE
    Commented Sep 24, 2013 at 6:41
0

This also works perfectly in wp_list_pages:

<?php wp_list_pages('title_li=&sort_column=menu_order,post_title'); ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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