I'm trying to sort my posts by the custom field artwork_title. When I use the following code, I just end up with one particular category of posts no matter what category archive I'm on.

Also pagination shows the correct number of pages but going to the next page always shows the same set of posts. Anyone see what I'm doing wrong?

<?php $query = new WP_Query(
        'posts_per_page' => 20,
        'orderby' => 'meta_value',
        'meta_key' => 'artwork_title',
        'order' => 'ASC'
    ) ); ?>

            <?php while ( $query->have_posts() ) : $query->the_post(); ?>

                <?php get_template_part( 'content', get_post_format() );

            <?php endwhile; ?>

@PieterGoosen suggested using pre_get_posts. I don't have any experience with that but I threw this together but I'm not getting any results back using it. I'm sure it's something stupid.

<?php add_action( 'pre_get_posts', 'sort_artwork_title' );?>

function sort_artwork_title( $query )
    if (is_admin()){

   if( $query->is_main_query() && is_post_type_archive() ) {

            $query->set('orderby', 'artwork_title');
            $query->set('posts_per_page', '20');
            $query->set('order', 'ASC' );
    return $query;
  • Do not use a custom query, use pre_get_posts Apr 8, 2015 at 14:04

1 Answer 1


To expand on @pieter-goosen's comment, you do indeed want to use pre_get_posts. In your example, by using WP_Query, you're overwriting the entire query and just resetting most parts of it to default. In fact, you're probably not seeing a specific category of posts at all. You should be seeing all posts since that's the default of the WP_Query class.

So instead, use pre_get_posts which modifies an existing query rather than creating a brand new one. Here's a [untested] snippet that should work in your functions.php file:

add_action( 'pre_get_posts', 'wpse183601_filter_category_query' );
function wpse183601_filter_category_query( $query ) {
    // only modify front-end category archive pages
    if( is_category() && !is_admin() && $query->is_main_query() ) {
        $query->set( 'posts_per_page','20' );
        $query->set( 'orderby','meta_value' );
        $query->set( 'meta_key','artwork_title' );
        $query->set( 'order','ASC' );
  • You answered as I was modifying my post to ask about pre_get_posts. Thanks so much. Looks like it's working. Question, where did that function name come from? Any reason it couldn't just be artwork_title_filter_category_query or something like that? Apr 8, 2015 at 15:28
  • 1
    @ThomasMartin you can name your function anything. Most of us just use the wpse**** prefix to have a unique name for functions. wpse means wordpress stackechange and the numbers is the post number :-). Just anote, remember to rename the call back function nameaccordingly Apr 8, 2015 at 15:36
  • Do I need to add anything to my archive.php, index.php or search.php pages? It seems to be working fine in archive pages but from the index the list of posts is random (or I don't see the order). Apr 8, 2015 at 16:12
  • Scratch that. I see that index is probably just sorting most recent posts (They were all created simultaneously, which is why I don't recognize the order.) Thanks again for your help. Apr 8, 2015 at 16:35
  • The if() clause in the snippet sets which pages (technically which queries) the sorting applied to. You had said Category pages so I went with that. You can use most other conditionals there without problem. Leave the last two things alone to avoid screwing up other parts of WordPress. If you really want to grok this, read the linked Codex page and even watch Nacin's "You Don't Know Query" talk on WordPress.tv.
    – mrwweb
    Apr 8, 2015 at 16:37

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.