SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.
SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.
Successfully reported this slideshow.
Activate your 30 day free trial to unlock unlimited reading.
10.
Every query object has its
own methods
is_author( ) is the same as calling
$wp_query->is_author( )
11.
function is_author( ) {
global $wp_query;
return $wp_query->is_author( );
}
12.
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( );
13.
But why do we call things like
wp_reset_postdata( ) and
wp_reset_query( )?
What about using query_posts( )?
How can you alter a query? What
about the main query?
14.
What is the main query,
and why should I care?
27.
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 );
}
28.
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
29.
wp-blog-header.php
// Load WordPress.
require dirname(__FILE__) . '/wp-load.php';
// Parse what to query, and query it.
wp();
// Load the theme.
ABSPATH . WPINC . '/template-loader.php';
30.
Before we get to the theme,
we have your posts.
Got it?
31.
Then why do we do this?
query_posts( 'author=5' );
get_header( );
while( have_posts( ) ) :
the_post( );
endwhile;
get_footer( );
32.
That's running 2* queries!
One, the query WordPress
thought we wanted.
Two, this new one you're
actually going to use.
33.
* Actually, WP_Query
doesn't run just one query.
It usually runs four.
34.
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. Slurp all metadata for these posts.
4. Slurp all terms for these posts.
35.
PROTIP
‘Measure twice, cut once’
is bad for performance.
36.
(A note, 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,
) );
41.
Powerful, but lacks context.
Problem 1: Conditional tags don't work yet.
42.
Powerful, but lacks context.
Problem 1: Conditional tags don't work yet.
Problem 2: Only works on the main query.
43.
Powerful, but lacks context.
Problem 1: Conditional tags don't work yet.
Problem 2: Only works on the main query.
Problem 3: WP_Query is waaay cooler.
44.
Introducing pre_get_posts
class WP_Query {
. . .
function &get_posts() {
$this->parse_query();
// Huzzah! Conditional tags are available.
do_action_ref_array( 'pre_get_posts',
array( &$this ) );
. . .
45.
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' );
46.
Still with us?
Good, ‘cause here’s where
things get hairy.
47.
'request' fires for the main query only.
'pre_get_posts' fires for every post query:
— get_posts()
— new WP_Query()
— That random recent posts widget.
— Everything.
50.
Main query only!
function nacin_alter_home ( $query ) {
if ( $wp_the_query === $query
&& $query->is_home() )
$query->set( 'author', '-5' );
}
add_action( 'pre_get_posts', 'nacin_alter_home' );
51.
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().
56.
class WP_Query {
. . .
function wp_reset_query( ) {
// Restore the reference to
$wp_the_query
unset( $wp_query );
$wp_query =& $wp_the_query;
// Reset the globals, too.
wp_reset_postdata( );
. . .
57.
Calling the_post( )?
wp_reset_query( ) will reset $wp_query
and and the globals.
Calling $my_query->the_post( )?
wp_reset_postdata( ) will reset the globals.
58.
New thing for core in 3.3!
Rather than:
$wp_the_query === $other_query_object
You'll be able to call:
$other_query_object->is_main_query( )
is_main_query( ), the function, will act on
$wp_query, like any other conditional tag.
59.
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( ).
60.
And Finally
request is a nice hook. pre_get_posts is more
powerful and flexible. Just use it properly.
Always check if you're modifying the main query
using $query === $wp_the_query
$query->is_main_query( ) in 3.3!