![Page 1: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/1.jpg)
WordCamp Netherlands 2012
![Page 2: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/2.jpg)
Andrew Nacin
Core Developer of WordPress and Tech Ninja at Audrey Capital
@nacin on Twitter [email protected]
![Page 3: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/3.jpg)
You Don’t Know Query
![Page 4: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/4.jpg)
What do you know?
![Page 5: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/5.jpg)
Conditional Tags
is_author( ), is_home( ), etc.
![Page 6: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/6.jpg)
query_posts( )
![Page 7: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/7.jpg)
Ways to query
query_posts( ) new WP_Query( ) get_posts( )
![Page 8: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/8.jpg)
The Loop
while ( have_posts( ) ) :
the_post( ); endwhile;
![Page 9: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/9.jpg)
A secondary loop
$query = new WP_Query( … ); while ( $query->have_posts( ) ) :
$query->the_post( ); endwhile;
![Page 10: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/10.jpg)
An array of posts
$result = get_posts( … ); foreach ( $result as $post_obj ) { }
![Page 11: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/11.jpg)
What don’t you know?
![Page 12: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/12.jpg)
Every query object has its own methods
is_author( ) is the same as calling $wp_query->is_author( )
![Page 13: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/13.jpg)
function is_author( ) {
global $wp_query;
return $wp_query->is_author( ); }
![Page 14: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/14.jpg)
With the regular loop
while ( have_posts( ) ) :
the_post( ); if ( is_author( ) ) echo "An author query.";
endwhile;
![Page 15: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/15.jpg)
With the regular loop
while ( have_posts( ) ) :
the_post( ); if ( $wp_query->is_author( ) ) echo "An author query.";
endwhile;
![Page 16: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/16.jpg)
A secondary loop
$query = new WP_Query( … ); while ( $query->have_posts( ) ) :
$query->the_post( ); if ( $query->is_author( ) ) echo "An author query.";
endwhile;
![Page 17: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/17.jpg)
A secondary loop
$query = new WP_Query( … ); while ( $query->have_posts( ) ) :
$query->the_post( ); if ( $query->is_author( ) ) echo "An author query.";
endwhile;
![Page 18: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/18.jpg)
A secondary loop
$query = new WP_Query( … ); while ( $query->have_posts( ) ) :
$query->the_post( ); if ( $query->is_author( ) ) echo "An author query.";
endwhile;
![Page 19: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/19.jpg)
If you do: $my_query = new WP_Query( $query ); You can do: while ( $my_query->have_posts( ) ) : $my_query->the_post( ); endwhile; wp_reset_postdata( );
![Page 20: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/20.jpg)
Why do we call functions like wp_reset_postdata( ) and wp_reset_query( )? What about using query_posts( )? How can you alter a query? How can you alter the main query?
![Page 21: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/21.jpg)
What is the main query, and why should I care?
![Page 22: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/22.jpg)
wp-blog-header.php // Load the WordPress bootstrap require './wp-load.php'; // Do magic wp( ); // Decide which template files to load require WPINC . '/template-loader.php';
![Page 23: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/23.jpg)
Let's look in the bootstrap: $wp_the_query = new WP_Query(); $wp_query =& $wp_the_query;
![Page 24: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/24.jpg)
Quick lesson on PHP references
$a = 4; $b =& $a; $b = 2; var_dump( $a ); // int(2) $a = 6; var_dump( $b ); // int(6)
![Page 25: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/25.jpg)
So: So the real main query is in $wp_the_query. And a live copy of it is stored in $wp_query.
![Page 26: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/26.jpg)
wp-blog-header.php // Load the WordPress bootstrap require './wp-load.php'; // Do magic wp( ); // Decide which template files to load require WPINC . '/template-loader.php';
![Page 27: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/27.jpg)
wp-blog-header.php // Load the WordPress bootstrap require './wp-load.php'; // Do magic wp( ); // Decide which template files to load require WPINC . '/template-loader.php';
![Page 28: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/28.jpg)
What is that wp( ) call?
function wp( $query_vars = '' ) { global $wp;
$wp->main( $query_vars );
}
![Page 29: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/29.jpg)
Holy $!@?, what just happened?
![Page 30: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/30.jpg)
In the bootstrap:
$wp = new WP( ); So there's a wp( ) function, and a WP class.
![Page 31: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/31.jpg)
class WP { . . . function main( ) { $this->init( ); $this->parse_request( ); $this->send_headers( ); $this->query_posts( ); $this->handle_404( ); $this->register_globals( ); . . .
![Page 32: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/32.jpg)
class WP { . . . function main( ) { $this->init( ); $this->parse_request( ); $this->send_headers( ); $this->query_posts( ); $this->handle_404( ); $this->register_globals( ); . . .
![Page 33: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/33.jpg)
WP::parse_request( ) — Parses the URL using WP_Rewrite — Sets up query variables for WP_Query WP::query_posts( ) {
global $wp_the_query; $wp_the_query->query( $this->query_vars );
}
![Page 34: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/34.jpg)
Boom. SELECT SQL_CALC_FOUND_ROWS
wp_posts.* FROM wp_posts WHERE 1=1
AND wp_posts.post_type = 'post' AND wp_posts.post_status = 'publish'
ORDER BY wp_posts.post_date DESC LIMIT 0, 10
![Page 35: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/35.jpg)
wp-blog-header.php // Load WordPress. require './wp-load.php'; // Parse what to query. Then query it. wp( ); // Load the theme. require WPINC . '/template-loader.php';
![Page 36: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/36.jpg)
Before we get to the theme, we have your posts.
Got it?
![Page 37: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/37.jpg)
Then why do we do this?
query_posts( 'author=-5' ); get_header( ); while( have_posts( ) ) : the_post( ); endwhile; get_footer( );
![Page 38: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/38.jpg)
That's running 2* queries! One, the query WordPress thought we wanted. Two, this new one you're actually going to use.
![Page 39: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/39.jpg)
* Actually, WP_Query doesn't run just one query. It usually runs four.
![Page 40: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/40.jpg)
1. Get me my posts: SELECT SQL_CALC_FOUND_ROWS … FROM wp_posts LIMIT 0, 10
2. How many posts exist? SELECT FOUND_ROWS( )
3. Get all metadata for these posts. 4. Get all terms for these posts.
![Page 41: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/41.jpg)
(You can turn these off selectively…)
$my_query = new WP_Query( array( 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false,
) );
![Page 42: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/42.jpg)
</aside>
![Page 43: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/43.jpg)
PROTIP ‘Measure twice, cut once’ is bad for performance.
![Page 44: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/44.jpg)
Other problems with query_posts( )
![Page 45: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/45.jpg)
Pagination breaks. WordPress calculated paging using the query it did, not the query you did.
![Page 46: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/46.jpg)
query_posts( array( 'author' => -5, 'posts_per_page' => 25,
) ); This will not work well.
![Page 47: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/47.jpg)
You easily mess up globals.
This can break widgets and more.
![Page 48: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/48.jpg)
query_posts( ) is bad. Do we agree?
![Page 49: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/49.jpg)
Introducing pre_get_posts class WP_Query {
. . . function &get_posts() { $this->parse_query(); // Huzzah! do_action_ref_array( 'pre_get_posts', array( &$this ) ); . . .
![Page 50: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/50.jpg)
A truly awesome hook. function nacin_alter_home( $query ) {
if ( $query->is_home( ) ) $query->set( 'author', '-5' );
} add_action( 'pre_get_posts', 'nacin_alter_home' );
![Page 51: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/51.jpg)
Still with us?
Good, ‘cause here’s where things get complicated.
![Page 52: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/52.jpg)
'pre_get_posts' fires for every post query: — get_posts( ) — new WP_Query( ) — That random recent posts widget your client installed without you knowing. — Everything.
![Page 53: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/53.jpg)
What if I just want it on the main query?
![Page 54: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/54.jpg)
$wp_the_query makes a triumphant return.
![Page 55: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/55.jpg)
Main query only!
function nacin_alter_home( $query ) { global $wp_the_query; if ( $wp_the_query === $query && $query->is_home() ) $query->set( 'author', '-5' );
} add_action( 'pre_get_posts', 'nacin_alter_home' );
![Page 56: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/56.jpg)
Hmm. How does this work? $wp_the_query should never be modified. It holds the main query, forever. $wp_query keeps a live reference to $wp_the_query, unless you use query_posts( ).
![Page 57: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/57.jpg)
query_posts( 'author=-5' ); while ( have_posts( ) ) :
the_post( ); endwhile; wp_reset_query( );
![Page 58: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/58.jpg)
query_posts( 'author=-5' ); while ( have_posts( ) ) :
the_post( ); endwhile; wp_reset_query( );
![Page 59: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/59.jpg)
function query_posts( $query ) { // Break the reference to $wp_the_query unset( $wp_query ); $wp_query =& new WP_Query( $query ); return $wp_query;
}
![Page 60: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/60.jpg)
query_posts( 'author=-5' ); while ( have_posts( ) ) :
the_post( ); endwhile; wp_reset_query( );
![Page 61: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/61.jpg)
function wp_reset_query( ) { // Restore reference to $wp_the_query unset( $wp_query ); $wp_query =& $wp_the_query;
// Reset the globals, too. wp_reset_postdata( );
}
![Page 62: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/62.jpg)
Calling the_post( )? wp_reset_query( ) will reset $wp_query and the globals.
Calling $my_query->the_post( )?
wp_reset_postdata( ) will reset the globals.
![Page 63: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/63.jpg)
New in WordPress 3.3!
Rather than: $wp_the_query === $other_query_object
You can call:
$other_query_object->is_main_query( ) is_main_query( ), the function, will act on $wp_query, like any other conditional tag.
![Page 64: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/64.jpg)
What about page templates?
![Page 65: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/65.jpg)
/* Template: My Template */ query_posts( $query_string .
'&author=-5&posts_per_page=25' ); get_header( ); while ( have_posts( ) ) :
the_post( ); endwhile;
![Page 66: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/66.jpg)
function nacin_my_template( $query ) { if ( ! $query->is_main_query( ) ) return; if ( ! is_page_template( 'my-template.php' ) ) return; $query->set( 'author', '-5' ); $query->set( 'posts_per_page', '25' );
} add_action( 'pre_get_posts',
'nacin_my_template' );
![Page 67: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/67.jpg)
Some Lessons
Every WP_Query object has methods that mimic the global conditional tags. The global conditional tags apply to $wp_query, the main or current query. $wp_query is always the main query, unless you use query_posts( ). Restore it with wp_reset_query( ).
![Page 68: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/68.jpg)
pre_get_posts is a powerful and flexible hook. Just use it properly. Always check if you're modifying the main query using $query->is_main_query( )
And Finally
![Page 69: You Don't Know Query (WordCamp Netherlands 2012)](https://reader034.vdocuments.mx/reader034/viewer/2022052505/5558a92dd8b42a2a738b5251/html5/thumbnails/69.jpg)
Thanks! Questions?
@nacin