1

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 );

}

2 Answers 2

2

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.

1
  • 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
    Commented Mar 22, 2011 at 22:52
3

Hook into the action 'pre_get_posts'.
Example:

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;
}
1
  • Thanks for your help! Will upvote when I get some cred :)
    – patnz
    Commented Mar 22, 2011 at 22:54

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.