WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is it possible to edit the main query on a page using the pre_get_posts filter? I tried but it doesn't seem to work.

function pre_wp_queries( $query ) {
    // only trigger on main qyery
    if ( !$query->is_main_query() )

    if (is_page_template('TEMPLATE_NAME.php')) {
        $query->query_vars['pagename'] = null;
        $query->query_vars['post_type'] = 'post';
        $query->query_vars['posts_per_page'] = 3;
        $query->query_vars['cat'] = 13;
add_action('pre_get_posts', 'pre_wp_queries', 9001);

On the header.php I use this line to check if it worked:


It displays:

SELECT wp_posts.*
FROM wp_posts
  AND wp_posts.post_type = 'post'
ORDER BY wp_posts.post_date DESC 

So it changed the posttype but not the rest. Also it goes to the 404 page. In fact dumping the $GLOBALS['wp_query']->queried_object gives back the original page. I tried this on 2 WP installs same behaviour on both.

Is this correct behaviour, or am I missing something?

share|improve this question
Have you tried it in a simpler form? e.g: function pre_wp_queries($q) { $q->set('posts_per_page', 3); } Just to see if it works? (tested in a sandbox myself and it works). You may also need to check that there aren't any query_posts calls in the template, they will overrule anything done in the pre_get_posts hook, afaik. – totels Nov 12 '12 at 10:40
Right now I don't even know where I deeded this. I know I 'solved' it / had a work around. Also There was no query_posts. I know it's bad for performance. Consider closed. – janw Nov 12 '12 at 14:20

Explaining the object.

You don't have to manually force data into those class properties. The whole $wp_query object has a bunch of internal methods that you should use to set values. Here's an example:

public function query( $query )
    if (
        'SOME_POST_TYPE' !== $query->get( 'post_type' )
        OR ! $query->is_main_query()
        OR ! $query->is_archive()
        OR ! $query->is_post_type_archive()
        OR ! is_page_template( 'TEMPLATE_NAME.php' )
        return $query;

    $query->set( 'posts_per_page', -1 );
    $query->set( 'numberposts', -1 );

    return $query;

Built in taxonomies: Categories & Tags

A Single term/category/taxon

If you want to query for categories and set them manually, then you have a pretty easy task, as you don't have to to a tax_query:

$query->set( 'category__in', 13 );

Multiple terms/categories/taxons

If you need to query for multiple categories:

$query->set( 'category__and', array( 12, 13 ) );

You can read more about this on the Codex page for the WP_Query class. And of course you have the same possibilities for the built in post_tag/Tags taxonomy.

Custom taxonomies

Here things slightly get more complicated: You'll need to use a tax_query. Keep in mind that this needs an array( array() ). In plain words: One surrounding array and inside this one another one. If you don't do this, WP will fail silently. Example:

$tax_query = array(
         'taxonomy' => 'event_type_taxonomy'
        ,'field'    => 'id'
        ,'terms'    => array( 12, 13 )
        ,'operator' =>'IN'
$query->set( 'tax_query', $tax_query );

Extended explanation again on the Codex page.

share|improve this answer

Your Answer


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.