Exploring the Future Potential of AI-Enabled Smartphone Processors
You don’t know query - WordCamp UK Edinburgh 2012
1. You Don’t Know Query
WordCamp Edinburgh UK
14-15 July 2012
2. Scott Cariss aka Brady
• Lead developer at Philosophy Design.
• Moderator at WordPress Answers
(http://wordpress.stackexchange.com)
• WordPress plugin developer and enthusiast
scott@philosophydesign.com
@l3rady on Twitter
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?
Let's dig in
15. wp-blog-header.php
// Load the WordPress bootstrap require
dirname( __FILE__ ) . '/wp-load.php';
// Decide which template files to load
ABSPATH . WPINC . '/template-loader.php';
16. Let’s look in the bootstrap:
$wp_the_query = new WP_Query();
$wp_query =& $wp_the_query;
25. 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 );
}
26. What do we get?
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
32. 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. Pull down all metadata for these posts.
4. Pull down all terms for these posts.
33. Instead of query_posts()?
We can use this:
// In WP::parse_request()
$this->query_vars = apply_filters(
'request', $this->query_vars );
34. We can modify query variables in mid
air:
function brady_filter_out_author( $qvs )
{
if( ! Isset( $qvs*‘author’+ ) )
$qvs*‘author’+ = ‘-5’;
return $qvs;
}
add_filter( “request”, “brady_filter_out_author”);
35. Powerful, but lacks context.
Problems:
1. Conditional tags don’t work yet.
2. Only works on the main query.
3. WP_Query is way cooler.
36. Introducing pre_get_posts
class WP_Query
{
...
function &get_posts()
{
$this->parse_query();
// OMG! Conditional tags are available!!
do_action_ref_array( 'pre_get_posts', array( &$this ) );
}
...
}
37. Lets kill off query_posts()!
function brady_alter_home( $query )
{
if ( $query->is_home( ) )
$query->set( 'author', '-5' );
}
add_action(
'pre_get_posts', ‘brady_alter_home' );
39. ‘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.
42. Main query only!
function brady_alter_home( $query )
{
if ( $query->is_home( ) &&
$wp_the_query === $query )
$query->set( 'author', '-5' );
}
add_action(
'pre_get_posts', ‘brady_alter_home' );
43. 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().
47. 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( );
...
}
....
}
48. 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.
49. Since WordPress 3.3!
Rather than:
$wp_the_query === $other_query_object
You‘re able to call:
$other_query_object->is_main_query( )
50. 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( ).
51. 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->is_main_query( )
$query === $wp_the_query before 3.3