Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
You Don’t Know Query   WordPress London   WordPress London    May 16, 2012
Scott Cariss aka Brady         Scott Cariss aka Brady• Lead developer at Philosophy Design.     dd l            hil    h  ...
You Don t Know QueryYou Don’t Know Query
What do you know?What do you know?
Conditional Tags             Conditional Tagsis_author(), is_home(), etc.
Who has ever heard of query_posts()?Who has ever heard of query posts()?
Ways to query           Ways to queryquery_posts()new WP_Query()new WP Query()get_posts()
The loop                   The loopif( have_posts() )   while( have_posts() ):   while( have posts() ):     the_post();  e...
What don t you know?What don’t you know?
Every query object has its own                methodsis_author() is the same as calling$wp_query >is_author()$wp query‐>is...
function is_author(){  global $wp_query;    return $wp_query >is_author();    return $wp query‐>is author();}
If you do: $my_query new WP Query( $query );$my query = new WP_Query( $query ); You can do: while ( $my_query >have_posts(...
But why do we call things like     h d        ll hi     likwp_reset_postdata( ) and p_     _p         ()wp_reset_query( )?...
What is the main query, and why          should I care?
Let s dig in.Lets dig in
wp‐blog‐header.php          wp blog header php// Load the WordPress bootstrap require//    d h      d        b            ...
Let s look in the bootstrap:     Let’s look in the bootstrap:$wp_the_query = new WP_Query();$wp_query & $wp_the_query;$wp ...
Quick lesson on PHP references    Quick lesson on PHP references// References in PHP are a means to access the same variab...
So:The real main query is in$wp_the_query.$wp the query.And a live copy of it is stored in$wp_query$wp query
wp‐blog‐header.php          wp blog header php// Load the WordPress bootstrap require//    d h      d        b            ...
What is that wp() call?           What is that wp() call?function wp( $query_vars =  ){  global $wp;      $wp >main( $quer...
Holy $!@?, what just happened?Holy $!@? what just happened?
In the bootstrap:             In the bootstrap:$wp = new WP()So there’s a wp() function, and a WP class.
class WPclass WP{   ...   function main( )   f                ()   {        $this‐>init( );       $this‐>parse_request( );...
class WPclass WP{   ...   function main( )   f                ()   {        $this‐>init( );       $this‐>parse_request( );...
WP::parse_request( ) WP                 t( )Parses the URL using WP_RewriteSets up query variables for WP_QueryWP::query_p...
What do we get?           What do we get?SELECT SQL_CALC_FOUND_ROWS   wp_posts. FROM  wp posts.* FROMwp_posts WHERE 1=1   ...
wp‐blog‐header.php          wp blog header php// Load WordPress//    d     ddirname( __FILE__ ) . /wp‐load.php;         ( ...
Before we get to the theme, we have              your posts.Are we clear so far?
Then why do we do this?       Then why do we do this?query_posts( author=5 );           ( h       )g _get_header( );      ...
That s running 2 queries!      That’s running 2* queries!One, the query WordPressthought we wanted.thought we wanted.Two, ...
* Actually, WP_Query doesnt run just onequery. It usually runs four. query. It usually runs four.
1. Get me my posts: SELECT         _     _        _     SQL_CALC_FOUND_ROWS …     FROM wp_posts LIMIT 0, 10 2. How many po...
Instead of query_posts()?       Instead of query posts()?We can use this:// In WP::parse_request()$this >query_vars = appl...
We can modify query variables in mid                    air:function brady_filter_out_author( $qvs ){  if( ! Isset( $qvs[‘...
Powerful, but lacks context.     Powerful but lacks contextProblems:1. Conditional tags don’t work yet.2. Only works on th...
Introducing pre_get_posts        Introducing pre get postsclass WP_Query  l WP Q{    . . .   function &get_posts()   {   {...
Lets kill off query_posts()!      Lets kill off query posts()!function brady_alter_home( $query ){  if ( $query‐>is_home( ...
Still with us?               Still with us?Good ‘cause here’s where things get hairy.
‘request’ fires for the main query only.‘       ’ fi f h          i          l‘pre_get_posts’ fires for every post query:•...
What if I just want it on the       main query?
$wp_the_query makes a  triumphant return.
Main query only!            Main query only!function brady_alter_home( $query )f      i b d l        h      ($     ){  if ...
Hmm. How does this work?     Hmm How does this work?$wp_the_query should never be modified. It                 q y holds th...
query_posts( author=‐5 ); while ( have_posts( ) ) : while ( have posts( ) ) :  the_post( );endwhile;wp_reset_query( ); wp ...
class WP_Query  l WP Q{    . . .    function &query_posts( $query )   {        // Break the reference to $wp_the_query    ...
query_posts( author=‐5 ); while ( have_posts( ) ) : while ( have posts( ) ) :  the_post( );endwhile;wp_reset_query( ); wp ...
class WP_Queryclass WP Query{   . . .   function wp_reset_query( )   f                           ()   {        // Restore ...
Calling the_post( )? wp_reset_query( ) will reset   $wp_query and and the globals.       p_q y               gCalling $my_...
Since WordPress 3.3!         Since WordPress 3 3!Rather than: $wp_the_query$wp the query === $other_query_object          ...
Some Lessons              Some LessonsEvery WP_Query object has methods that mimic       g                    g  the globa...
And finally                 And finallyrequest is a nice hook. pre_get_posts is more   p  powerful and flexible. Just use i...
Thank you! Any questions?     Thank you! Any questions?Further in‐depth discussion on query_posts():• @l3rady on Twitter. ...
Upcoming SlideShare
Loading in …5
×

WordPress London 16 May 2012 - You don’t know query

2,265 views

Published on

How to alter the main WordPress query the correct way. No more query_posts() pwease!

by Scott Cariss of Philosophy Design

Philosophy is a thought-led brand and digital consultancy based in London.

Published in: Technology, Business

WordPress London 16 May 2012 - You don’t know query

  1. 1. You Don’t Know Query WordPress London WordPress London May 16, 2012
  2. 2. Scott Cariss aka Brady Scott Cariss aka Brady• Lead developer at Philosophy Design. dd l hil h i• Moderator at WordPress Answers  ( p (http://wordpress.stackexchange.com/) p g )• WordPress plugin developer and enthusiast WordPress plugin developer and enthusiastscott@philosophydesign @ hil h d i@l3rady on Twitter
  3. 3. You Don t Know QueryYou Don’t Know Query
  4. 4. What do you know?What do you know?
  5. 5. Conditional Tags Conditional Tagsis_author(), is_home(), etc.
  6. 6. Who has ever heard of query_posts()?Who has ever heard of query posts()?
  7. 7. Ways to query Ways to queryquery_posts()new WP_Query()new WP Query()get_posts()
  8. 8. The loop The loopif( have_posts() ) while( have_posts() ): while( have posts() ): the_post(); endwhile();
  9. 9. What don t you know?What don’t you know?
  10. 10. Every query object has its own  methodsis_author() is the same as calling$wp_query >is_author()$wp query‐>is author()
  11. 11. function is_author(){ global $wp_query; return $wp_query >is_author(); return $wp query‐>is author();}
  12. 12. If you do: $my_query new WP Query( $query );$my query = new WP_Query( $query ); You can do: while ( $my_query >have_posts( ) ) :while ( $my query‐>have posts( ) ) : $my_query‐>the_post( ); endwhile;wp_reset_postdata( ); 
  13. 13. But why do we call things like h d ll hi likwp_reset_postdata( ) and p_ _p ()wp_reset_query( )? What about using query_posts( )? How can you alter a query? What aboutHow can you alter a query? What aboutthe main query? 
  14. 14. What is the main query, and why  should I care?
  15. 15. Let s dig in.Lets dig in
  16. 16. wp‐blog‐header.php wp blog header php// Load the WordPress bootstrap require// d h d b idirname( __FILE__ ) . /wp‐load.php;  ( __ __ ) p p p// Decide which template files to load// Decide which template files to loadABSPATH . WPINC . /template‐loader.php; 
  17. 17. Let s look in the bootstrap: Let’s look in the bootstrap:$wp_the_query = new WP_Query();$wp_query & $wp_the_query;$wp query =& $wp the query;
  18. 18. Quick lesson on PHP references Quick lesson on PHP references// References in PHP are a means to access the same variable content // R f i PHP t th i bl t t by different names.$a = 4;$b =& $a;// It means that $a and $b now point to the same content.$b = 2;$b 2var_dump( $a ); // int(2)$a = 6;var_dump( $b ); // int(6) 
  19. 19. So:The real main query is in$wp_the_query.$wp the query.And a live copy of it is stored in$wp_query$wp query
  20. 20. wp‐blog‐header.php wp blog header php// Load the WordPress bootstrap require// d h d b idirname( __FILE__ ) . /wp‐load.php;  ( __ __ ) p p p// Do magic// Do magicwp();// Decide which template files to load// Decide which template files to loadABSPATH . WPINC . /template‐loader.php; 
  21. 21. What is that wp() call? What is that wp() call?function wp( $query_vars =  ){ global $wp;  $wp >main( $query_vars $wp‐>main( $query vars );} 
  22. 22. Holy $!@?, what just happened?Holy $!@? what just happened?
  23. 23. In the bootstrap: In the bootstrap:$wp = new WP()So there’s a wp() function, and a WP class.
  24. 24. class WPclass WP{ ... function main( ) f () {  $this‐>init( ); $this‐>parse_request( ); $this‐>send_headers( ); $ $this‐>query posts( ); q y_p ( ); $this‐>handle_404( ); $this‐>register_globals( );  } . . . }
  25. 25. class WPclass WP{ ... function main( ) f () {  $this‐>init( ); $this‐>parse_request( ); $this‐>send_headers( ); $ $this‐>query posts( ); q y_p ( ); $this‐>handle_404( ); $this‐>register_globals( );  } . . . }
  26. 26. WP::parse_request( ) WP t( )Parses the URL using WP_RewriteSets up query variables for WP_QueryWP::query_posts( ){ global $wp_the_query; $ p_ $wp the_q y q y( $ query‐>query( $this‐>query vars );  q y_ );} 
  27. 27. What do we get? What do we get?SELECT SQL_CALC_FOUND_ROWS  wp_posts. FROM wp posts.* FROMwp_posts WHERE 1=1  AND wp_posts.post_type = post‘ AND wp_posts.post_status =  publish ORDER AND wp posts post status = publish ORDERBY wp_posts.post_date DESC LIMIT 0, 10 
  28. 28. wp‐blog‐header.php wp blog header php// Load WordPress// d ddirname( __FILE__ ) . /wp‐load.php;  ( __ __ ) p p p// Parse what to query, and query it. // Parse what to query and query itwp(); // Load the theme.// Load the themeABSPATH . WPINC . /template‐loader.php; 
  29. 29. Before we get to the theme, we have  your posts.Are we clear so far?
  30. 30. Then why do we do this? Then why do we do this?query_posts( author=5 ); ( h )g _get_header( ); ()while( have_posts( ) ) : while( have posts( ) ) : the_post( );endwhile;get_footer( ); 
  31. 31. That s running 2 queries! That’s running 2* queries!One, the query WordPressthought we wanted.thought we wanted.Two, this new one you’reactually going to use.actually going to use
  32. 32. * Actually, WP_Query doesnt run just onequery. It usually runs four. query. It usually runs four.
  33. 33. 1. Get me my posts: SELECT _ _ _ SQL_CALC_FOUND_ROWS … FROM wp_posts LIMIT 0, 10 2. How many posts exist?2 How many posts exist? SELECT FOUND_ROWS() 3. Pull down all metadata for these posts.4. Pull down all terms for these posts. 4 Pull down all terms for these posts
  34. 34. Instead of query_posts()? Instead of query posts()?We can use this:// In WP::parse_request()$this >query_vars = apply_filters(  request$this‐>query vars = apply filters( request,  $this‐>query_vars ); 
  35. 35. We can modify query variables in mid  air:function brady_filter_out_author( $qvs ){ if( ! Isset( $qvs[‘author’] ) ) $qvs[‘author’] = ‘‐5’; return $qvs;}
  36. 36. Powerful, but lacks context. Powerful but lacks contextProblems:1. Conditional tags don’t work yet.2. Only works on the main query.2 Only works on the main query3. WP_Query is way cooler.
  37. 37. Introducing pre_get_posts Introducing pre get postsclass WP_Query l WP Q{  . . . function &get_posts() { {  $this‐>parse_query();  // OMG! Conditional tags are available!! do_action_ref_array( pre_get_posts, array( &$this ) );  } . . . }
  38. 38. Lets kill off query_posts()! 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. 39. Still with us? Still with us?Good ‘cause here’s where things get hairy.
  40. 40. ‘request’ fires for the main query only.‘ ’ fi f h i l‘pre_get_posts’ fires for every post query:• get_posts()• new WP_Query()• That random recent posts widget. That random recent posts widget• Everything.
  41. 41. What if I just want it on the main query?
  42. 42. $wp_the_query makes a triumphant return.
  43. 43. Main query only! Main query only!function brady_alter_home( $query )f i b d l h ($ ){ if ( $query‐>is_home( ) && $wp_the_query === $query )  $wp the query === $query ) $query‐>set( author, ‐5 );}add_action(  pre_get_postsadd action( pre get posts,  ‘brady_alter_home );
  44. 44. Hmm. How does this work? Hmm How does this work?$wp_the_query should never be modified. It  q y holds the main query, forever. $wp_query k$ keeps a live reference to  li f $wp_the_query, unless you use query_posts(). 
  45. 45. query_posts( author=‐5 ); while ( have_posts( ) ) : while ( have posts( ) ) : the_post( );endwhile;wp_reset_query( ); wp reset query( );
  46. 46. class WP_Query l WP Q{  . . .  function &query_posts( $query ) {  // Break the reference to $wp_the_query // Break the reference to $wp the query unset( $wp_query );  $wp_query =& new WP_Query( $query );  ... } ...}
  47. 47. query_posts( author=‐5 ); while ( have_posts( ) ) : while ( have posts( ) ) : the_post( );endwhile;wp_reset_query( ); wp reset query( );
  48. 48. class WP_Queryclass WP Query{ . . . function wp_reset_query( ) f () {  // Restore the reference to $wp_the_query unset( $wp_query ); $wp_query =& $wp_the_query;  // // Reset the globals, too. g , wp_reset_postdata( ); . . .  } ....}
  49. 49. Calling the_post( )? wp_reset_query( ) will reset  $wp_query and and the globals.  p_q y gCalling $my_query‐>the_post( )? C lli $ h ( )? wp_reset_postdata( ) will reset the globals. 
  50. 50. Since WordPress 3.3! Since WordPress 3 3!Rather than: $wp_the_query$wp the query === $other_query_object $other query objectYou‘re able to call: $other_query_object >is_main_query( ) $other query object‐>is main query( )
  51. 51. Some Lessons Some LessonsEvery WP_Query object has methods that mimic  g g the global conditional tags.The global conditional tags apply to $wp_query, Th l b l di i l l $ the main or current query. $wp_query i l$ is always the main query, unless you  th i l use query_posts( ). Restore it with  wp_reset_query( ).
  52. 52. And finally And finallyrequest is a nice hook. pre_get_posts is more  p powerful and flexible. Just use it properly.  p p yAlways check if youre modifying the main query Al h k if dif i h i using $query‐>is_main_query( ) $query === $wp_the_query b f$ $ th before 3.3 33
  53. 53. Thank you! Any questions? Thank you! Any questions?Further in‐depth discussion on query_posts():• @l3rady on Twitter. @l3rady on Twitter.• Down the pub after presentations.

×