What’s Your Query? WCCHI 2013

The What, Where, Why, and Why Not

-Jarrod Pyper

This is not about jQuery. Sorry.

Posts 3 Ways

 
There are 3 ways to request posts from WP:
 

 

Section I: query_posts()
-Don’t Use It.

End of Section I

Y U No query_posts()?

“query_posts() is wasteful and ungrateful”.
-query_posts() own mother.

 

At best, you’re doubling the amount of database queries.

At worst, you’re breaking other parts of the page and other plugins.

At least use wp_reset_query() when you’re done.

Section II: WP_Query()
-BFF

Everything you could want in a friend

Always Prepared – Runs 4 queries for you

 

Everything you could want in a friend

Easy to get along with

3 Ways to Scale Back WP_Query()

Digital Field Trip
http://alexking.org/speaking/core-competency/index.php#/queries-02-wp-query-simple

Section III: get_posts()

get_posts() – Fastest Stock Option

The default arguments setup is our fastest choice of the 3

Another Field Trip
http://wordpress.stackexchange.com/a/1755/20813

Important Things to Remember

Typical WP_Query format is:

 

$args = array(
    'post_type' => 'my_post_type',
    'posts_per_page' => -1,
    'orderby' => 'rand'
);
$my_query = new WP_Query($args);

while( $my_query->have_posts() ) : $my_query->the_post();
    //Do stuff
endwhile;
wp_reset_postdata();

If you can’t be bothered to listen to reason…

If you’re still going to use query_posts or just realized why something was breaking on a site and need to fix it before lunch:

wp_reset_query();

Important Things to Remember

If you need to alter the main query (as query_posts() does) here’s a better way:

 

function my_other_query( $query ) {
    if( $query->is_main_query() ) {
        //Yeah it's the main one - do something to alter it
        $query->set('post_type', 'my_post_type');
    }
}
add_filter('pre_get_posts', 'my_other_query');

Section IV:Tricky WP_Query arguments

Querying by Custom Fields With Meta Query

$args = array(
	'post_type' => 'product',
	'meta_query' => array(
		array(
			'key' => 'color',
			'value' => 'blue',
			'compare' => 'NOT LIKE'
		)
	)
);
$query = new WP_Query( $args );
$args = array(
	'post_type' => 'product',
	'meta_query' => array(
		'relation' => 'OR',
		array(
			'key' => 'color',
			'value' => 'blue',
			'compare' => 'NOT LIKE'
		),
		array(
			'key' => 'price',
			'value' => array( 20, 100 ),
			'type' => 'numeric',
			'compare' => 'BETWEEN'
		)
	)
);
$query = new WP_Query( $args );

Querying by Taxonomy With Tax Query

$args = array(
	'post_type' => 'post',
	'tax_query' => array(
		'relation' => 'OR',
		array(
			'taxonomy' => 'category',
			'field' => 'slug',
			'terms' => array( 'quotes' )
		),
		array(
			'taxonomy' => 'post_format',
			'field' => 'slug',
			'terms' => array( 'post-format-quote' )
		)
	)
);
$query = new WP_Query( $args );

In The Wild – Another Field Triphttp://hellothisisjeff.com/

Thanks! – Questions?

Hot Tips!

Function for Printing Arrays and Objects

print_r is nice but is not easy to read, this function lets you specify the variable to print, a short message to print before the variable output, and wether you are echoing or returning the entire thing (useful for using the error_log).

function printr($out, $msg='out', $return=false) {
	if($return == false)
                echo '<pre style="overflow: scroll;">'.$msg.': '.print_r($out,1).' |</pre>';
        else
                return '<pre style="overflow: scroll;">'.$msg.': '.print_r($out,1).' |</pre>';
}

Outputting Errors on a Single Page Via Querystring

Add this to your wp_config.php file. This will allow you to get all of your php errors and warnings output to the page you are on by putting “?errors=on” at the end of your URL. This can come in handy for debugging or analyzing a single page on a live site.

 

if ( isset($_GET['errors']) && $_GET['errors'] == 'on'){
	@ini_set('display_errors','On');
	define('WP_DEBUG', true);
} else {
	define('WP_DEBUG', false);
}

Output a Database Table

This defaults to outputting the current blog’s options table. Familiarity with SQL and the WP database structure recommended to use this effectively.
function v_database_output($atts) {
	global $wpdb;

	extract( shortcode_atts( array(
		'blogid' => '',		//Not entering a blogid will result in current blog being used
		'table' => $wpdb->options, //Default to current blog's options table
		'columns' => '*',		//Default to get all columns from table
		'prefix' => 'yes'
	), $atts ));
	if($table != $wpdb->options) {
		if($blogid != '')
			$table = $wpdb->base_prefix.$blogid.'_'.$table;
		else
			$table = $wpdb->prefix.$table;
	}
	if( $prefix == 'no' )
		$table = $table;

	$query = 'SELECT '.$columns.' FROM '.$table;

	$results = $wpdb->get_results("$query");

	$out = 'Your query: '.$query.'<br/><br/><pre style="overflow:scroll;">'.print_r($results,1).'</pre>';

	return $out;
}
add_shortcode('dbquery', 'v_database_output');