In our archive.php we show all the items which match our selected category. This works absolutely fine.

Then we improved it by adding (just before the loop) a sort and upping the posts per page from the default 10, like so:

$posts = query_posts($query_string . '&orderby=title&order=asc&posts_per_page=99'); 

This works even better.

Now, however we want to sort by more than one field, say menu_order then title. I don't see a way to do this using this query_posts / querystring syntax we have in place. Code samples all involve firing up a new WP_Query, losing track of the query_string. What's the solution?

  • 1
    Never use query_posts. See this question and this question for some hints on using pre_get_posts.
    – Milo
    Mar 5, 2015 at 20:49
  • @Milo i'm looking at those links now
    – hawbsl
    Mar 6, 2015 at 13:16

2 Answers 2


If you're altering the main query, always use pre_get_posts to alter query parameters before the query is run and before the template is loaded. This will be the most efficient and will not break pagination. As of v4, orderby accepts an array of arguments, which gives you the ability to have different order for each if necessary:

function my_get_posts( $query ){
    if( !is_admin() && $query->is_category() && $query->is_main_query() ){
        $query->set( 'posts_per_page', -1 ); // show all posts
        $query->set( 'orderby', array('menu_order' => 'ASC', 'title' => 'ASC') );
add_action( 'pre_get_posts', 'my_get_posts' );

There is ability to sort by more than one column. See here.

$args = array(
    'posts_per_page' => 99,
    'orderby'   => 'menu_order title',
    'order'     => 'ASC',

$query = new WP_Query( $args );
// do your stuff here...


Check out standard loop and why you should use wp_reset_postdata.

  • yeah but what about query_posts? your fresh WP_Query will ignore that
    – hawbsl
    Mar 6, 2015 at 13:15
  • Same thing, only query_posts is slower, check here: codex.wordpress.org/Function_Reference/query_posts. Quote "This function isn't meant to be used by plugins or themes.". Anyway, did you try $posts = query_posts($query_string . '&orderby=menu_order title&order=asc&posts_per_page=99');?
    – mjakic
    Mar 6, 2015 at 13:17

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.