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

How do I add custom variables to the wordpress query without having to hit the database twice. In the example below I want to add some meta filters. All this code works fine but I have been running query_posts() to execute it. I want to be able to add to the query before it is run by default so I don't have to query the db twice.

In this I was hoping if I modify $wp_query->query before it is executed my changes would be added to the query. The query is being changed fine, just not the output. Any ideas? Thanks.

add_action('pre_get_posts', 'my_custom_query'); 
function my_custom_query(){

if(isset($_SESSION['size']) && $_SESSION['size'] != 'all'){
    $cfilter[] = array( 'key' => 'cc_size', 'value' => $_SESSION['size'] );

if(isset($_SESSION['gender']) && $_SESSION['gender'] != 'all'){
    $cfilter[] = array( 'key' => 'cc_gender', 'value' => $_SESSION['gender'] );

$extraArgs = array(
    'orderby' => 'post-title',
    'paged' => get_query_var('paged')

if(!empty($cfilter)){ $extraArgs['meta_query'] = $cfilter; }

global $wp_query;
$wp_query->query = array_merge( $wp_query->query, $extraArgs );


share|improve this question
up vote 2 down vote accepted

As toscho said, you can modify the query in the pre_get_posts hook. That hook gets the query object passed as an argument, so you don't have to read a global variable.

add_action( 'pre_get_posts', 'wpse12692_pre_get_posts' ); 
function wpse12692_pre_get_posts( &$wp_query )
    if( isset( $_SESSION['size'] ) && $_SESSION['size'] != 'all' )
        $wp_query->query_vars['meta_query'] = array(
            'key' => 'cc_size',
            'value' => $_SESSION['size'],

    if( isset( $_SESSION['gender'] ) && $_SESSION['gender'] != 'all' )
        $wp_query->query_vars['meta_query'] = array(
            'key' => 'cc_gender',
            'value' => $_SESSION['gender'],

    $wp_query->query_vars['orderby'] = 'post-title';
    // The next line is redundant, get_query_vars reads it from the global $wp_query object
    $wp_query->query_vars['paged'] = get_query_var('paged');

I see that your query depends on session variables. This can make it harder to forward a link to a page to someone else. Have you considered putting this in the URL and reading it from there? You can do that by creating extra rewrite rules.

share|improve this answer
Thanks, went with this is it makes sense to make use of wp_query as a parameter. I'm using sessions as I want the filters persistent but the permalink issue is a good point that I hadn't thought of. will have a play, thanks for your help! – patnz Mar 22 '11 at 22:52

Hook into the action 'pre_get_posts'.

add_action( 'pre_get_posts', 'no_sticky_on_front' );

function no_sticky_on_front()
    is_front_page() and $GLOBALS['wp_query']->query_vars['ignore_sticky_posts'] = TRUE;
share|improve this answer
Thanks for your help! Will upvote when I get some cred :) – patnz Mar 22 '11 at 22:54

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.