Setting multiple values to as sort_column

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?:

Read More
$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.!

Related posts

2 comments

  1. 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;
    
  2. This also works perfectly in wp_list_pages:

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

Comments are closed.