Register custom query args parameter for WP_Query()

After further research I figured out a solution. Given the following WP_Query:

<?php

new WP_Query(
    array(

        's' => 'some keyword', //keyword criterion
        'category' => 'some category', //taxonomy criterion

        '_spec' => 'some value', //custom criterion to be handled by the plugin

    )
);

?>

You can handle custom parameters using pre_get_posts in combination with posts_where:

<?php

add_action( 'pre_get_posts', 'my_pre_get_posts' ); //hook into the query before it is executed

$custom_where_string = ''; //used to save the generated where string between filter functions

function my_pre_get_posts( $query )
{
    global $custom_where_string;

    //if the custom parameter is used
    if(isset($query->query_vars['_spec'])){

        //here you can parse the contents of $query->query_vars['_spec'] to modify the query
        //even the first WHERE starts with AND, because WP adds a "WHERE 1=1" in front of every WHERE section
        $custom_where_string = 'AND ...';

        //only if the custom parameter is used, hook into the generation of the query
        add_filter('posts_where', 'my_posts_where'));
    }
}

function my_posts_where( $where )
{
    global $custom_where_string;

    //append our custom where expression(s)
    $where .= $custom_where_string;

    //clean up to avoid unexpected things on other queries
    remove_filter('posts_where', 'my_posts_where'));
    $custom_where_string = '';

    return $where;
}


?>

PS: Take a look at http://codex.wordpress.org/Class_Reference/WP_Query#Filters for manipulating other parts of the SQL-query (e.g. JOIN)

Leave a Comment