Fun with WP_Query

Erick Hitter
@ethitter



Lead WordPress Developer at Oomph, Inc.
WordPress 3.3 Core Contributor
WordCamp Boston Organizer
Plugin Author

What is WP_Query?

Using WP_Query

Most often, this is done in "The Loop" to use the results from the main query.

<?php
	if ( have_posts() ) {
		while( have_posts() ) {
			the_post();
		}
	}
?>

Using WP_Query: new WP_Query();

<?php
	$queried_posts = new WP_Query();

	if ( $queried_posts->have_posts() ) {
		while( $queried_posts->have_posts() ) {
			$queried_posts->the_post();
			//Use functions such as the_title() and the_content() here.
		}
	}

	wp_reset_query();
	wp_reset_postdata();
?>

Using WP_Query: get_posts();

<?php
	$queried_posts = get_posts();

	foreach( $queried_posts as $queried_post ) {
		setup_postdata( $queried_post );
	}

	wp_reset_postdata();
?>

Resetting Query and Postdata

Query Basics

Query Parameters

Sample Query 1

Five most recent posts

<?php $foo = new WP_Query( array(
	'posts_per_page' => 5
) ); ?>

Sample Query 2

Five most recent posts by author with ID 15

<?php $foo = new WP_Query( array(
	'posts_per_page' => 5,
	'author' => 15
) ); ?>

Sample Query 3

Five most recent posts by author with ID 15 in the toast

<?php $foo = new WP_Query( array(
	'posts_per_page' => 5,
	'author' => 15,
	'category_name' => 'toast'
) ); ?>

Sample Query 4

Five most recent posts or pages

<?php $foo = new WP_Query( array(
	'posts_per_page' => 5,
	'post_type' => array( 'post', 'page' )
) ); ?>

Using the tax_query

Using the tax_query

Using the toast example from Sample Query 3:

<?php $foo = new WP_Query( array(
	'posts_per_page' => 5,
	'author' => 15,
	'category_name' => 'toast'
) ); ?>

Becomes

<?php $foo = new WP_Query( array(
	'posts_per_page' => 5,
	'author' => 15,
	'tax_query' => array( array(
		'taxonomy' => 'category',
		'field' => 'slug',
		'terms' => 'toast'
	) )
) ); ?>

Using the tax_query: multiple queries

Querying two categories:

<?php $foo = new WP_Query( array(
	'posts_per_page' => 5,
	'author' => 15,
	'tax_query' => array( array(
		'taxonomy' => 'category',
		'field' => 'slug',
		'terms' => array( 'toast', 'breakfast' ),
		'operator' => 'AND'
	) )
) ); ?>

Querying a category and a tag:

<?php $foo = new WP_Query( array(
	'posts_per_page' => 5,
	'author' => 15,
	'tax_query' => array(
		'relation' => 'AND',
		array(
			'taxonomy' => 'category',
			'field' => 'slug',
			'terms' => 'toast'
		),
		array(
			'taxonomy' => 'post_tag',
			'field' => 'slug',
			'terms' => 'wheat'
		)
	)
) ); ?>

Using the tax_query: multiple queries

Querying a category and a tag, excluding subcategories:

<?php $foo = new WP_Query( array(
	'posts_per_page' => 5,
	'author' => 15,
	'tax_query' => array(
		'relation' => 'AND',
		array(
			'taxonomy' => 'category',
			'field' => 'slug',
			'terms' => 'toast',
			'include_children' => false
		),
		array(
			'taxonomy' => 'post_tag',
			'field' => 'slug',
			'terms' => 'wheat'
		)
	)
) ); ?>

Using the meta_query

Using the meta_query

Using the meta_query: multiple queries

get_query_var();

is_main_query();

query_posts();

Thankfully, a far-superior alternative exists!

The pre_get_posts action

Using the pre_get_posts action

<?php
	function bwpm_pre_get_posts( $query ) {
		//Herein, modify the query
	}

	add_action( 'pre_get_posts', 'bwpm_pre_get_posts' );
?>

The $query variable contains an object with two helpful methods:

Using the pre_get_posts action

Show only five posts on any and every archive page:

<?php
	function bwpm_pre_get_posts( $query ) {
		$query->set( 'posts_per_page', 5 );
	}

	add_action( 'pre_get_posts', 'bwpm_pre_get_posts' );
?>

To do the same on just the front page:

<?php
	function bwpm_pre_get_posts( $query ) {
		if ( $query->is_home() )
			$query->set( 'posts_per_page', 5 );
	}

	add_action( 'pre_get_posts', 'bwpm_pre_get_posts' );
?>

Using the pre_get_posts action

To do the same only when a posts_per_page value isn't set (is using the WordPress default):

<?php
	function bwpm_pre_get_posts( $query ) {
		if ( ! $query->get( 'posts_page_page' ) )
			$query->set( 'posts_per_page', 5 );
	}

	add_action( 'pre_get_posts', 'bwpm_pre_get_posts' );
?>

Questions?