You Don't Know Query (WordCamp Netherlands 2012)
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

You Don't Know Query (WordCamp Netherlands 2012)

on

  • 31,087 views

An update to a talk I gave at WordCamp Portland 2011, "You Don't Know Query" is an advanced development talk from March 25, 2012, in Utrecht, Netherlands.

An update to a talk I gave at WordCamp Portland 2011, "You Don't Know Query" is an advanced development talk from March 25, 2012, in Utrecht, Netherlands.

Statistics

Views

Total Views
31,087
Views on SlideShare
23,924
Embed Views
7,163

Actions

Likes
55
Downloads
228
Comments
8

32 Embeds 7,163

http://notnil-creative.com 3297
http://wp.smashingmagazine.com 2979
http://ja.naoko.cc 168
http://www.mukundthanki.me 146
http://www.smashingmagazine.com 137
https://twitter.com 99
http://wpdev.localhost.com 82
http://mukundthanki.me 48
http://www.scoop.it 45
http://mwp.smashingmagazine.com 29
http://wpcodex.qa.wp.rgnrtr.com 28
http://cloud.feedly.com 28
http://thewebdesign.collected.info 13
http://bheimseinblog.de 12
http://iammukundthanki.wordpress.com 10
http://wingmanpersonal.wordpress.com 7
http://pushkarcreations.com 7
http://www.linkedin.com 6
http://webcache.googleusercontent.com 4
http://bot.kz 3
https://si0.twimg.com 3
http://www.feedspot.com 2
http://reader.aol.com 1
http://rikautsumi.com 1
http://pmpetchiappan.wordpress.com 1
http://zootool.com 1
http://www.twylah.com 1
http://bottlenose.com 1
http://freerss.net 1
http://translate.googleusercontent.com 1
http://us-w1.rockmelt.com 1
https://notnil-creative.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

15 of 8 Post a comment

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • All my doubts are cleared. Thank you
    Are you sure you want to
    Your message goes here
    Processing…
  • For those of you who would love audio/video, have a look at wordpress.tv: http://wordpress.tv/2013/03/15/andrew-nacin-wp_query-wordpress-in-depth
    Are you sure you want to
    Your message goes here
    Processing…
  • Excellent presentation.
    Cleared my confusion about WP_Query
    Are you sure you want to
    Your message goes here
    Processing…
  • Awesome! I really often work with Wordpress. Those were all dark questions I all the time asked my self and googled a lot of times!
    Are you sure you want to
    Your message goes here
    Processing…
  • good slides
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

You Don't Know Query (WordCamp Netherlands 2012) Presentation Transcript

  • 1. WordCamp Netherlands 2012
  • 2. Andrew NacinCore Developer of WordPressand Tech Ninja at Audrey Capital@nacin on Twitternacin@wordpress.org
  • 3. You Don’t Know Query
  • 4. What do you know?
  • 5. Conditional Tagsis_author( ), is_home( ), etc.
  • 6. query_posts( )
  • 7. Ways to queryquery_posts( )new WP_Query( )get_posts( )
  • 8. The Loopwhile ( have_posts( ) ) : the_post( );endwhile;
  • 9. A secondary loop$query = new WP_Query( … );while ( $query->have_posts( ) ) : $query->the_post( );endwhile;
  • 10. An array of posts$result = get_posts( … );foreach ( $result as $post_obj ) {}
  • 11. What don’t you know?
  • 12. Every query object has itsown methodsis_author( ) is the same as calling$wp_query->is_author( )
  • 13. function is_author( ) { global $wp_query; return $wp_query->is_author( );}
  • 14. With the regular loopwhile ( have_posts( ) ) : the_post( ); if ( is_author( ) ) echo "An author query.";endwhile;
  • 15. With the regular loopwhile ( have_posts( ) ) : the_post( ); if ( $wp_query->is_author( ) ) echo "An author query.";endwhile;
  • 16. A secondary loop$query = new WP_Query( … );while ( $query->have_posts( ) ) : $query->the_post( ); if ( $query->is_author( ) ) echo "An author query.";endwhile;
  • 17. A secondary loop$query = new WP_Query( … );while ( $query->have_posts( ) ) : $query->the_post( ); if ( $query->is_author( ) ) echo "An author query.";endwhile;
  • 18. A secondary loop$query = new WP_Query( … );while ( $query->have_posts( ) ) : $query->the_post( ); if ( $query->is_author( ) ) echo "An author query.";endwhile;
  • 19. 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( );
  • 20. Why do we call functions likewp_reset_postdata( ) andwp_reset_query( )?What about using query_posts( )?How can you alter a query? Howcan you alter the main query?
  • 21. What is the main query,and why should I care?
  • 22. wp-blog-header.php// Load the WordPress bootstraprequire ./wp-load.php;// Do magicwp( );// Decide which template files to loadrequire WPINC . /template-loader.php;
  • 23. Lets look in the bootstrap:$wp_the_query = new WP_Query();$wp_query =& $wp_the_query;
  • 24. Quick lesson on PHP references$a = 4;$b =& $a;$b = 2;var_dump( $a ); // int(2)$a = 6;var_dump( $b ); // int(6)
  • 25. So:So the real main query is in$wp_the_query.And a live copy of it is stored in$wp_query.
  • 26. wp-blog-header.php// Load the WordPress bootstraprequire ./wp-load.php;// Do magicwp( );// Decide which template files to loadrequire WPINC . /template-loader.php;
  • 27. wp-blog-header.php// Load the WordPress bootstraprequire ./wp-load.php;// Do magicwp( );// Decide which template files to loadrequire WPINC . /template-loader.php;
  • 28. What is that wp( ) call?function wp( $query_vars = ) { global $wp; $wp->main( $query_vars );}
  • 29. Holy $!@?, what justhappened?
  • 30. In the bootstrap:$wp = new WP( );So theres a wp( ) function,and a WP class.
  • 31. class WP { . . . function main( ) { $this->init( ); $this->parse_request( ); $this->send_headers( ); $this->query_posts( ); $this->handle_404( ); $this->register_globals( ); . . .
  • 32. class WP { . . . function main( ) { $this->init( ); $this->parse_request( ); $this->send_headers( ); $this->query_posts( ); $this->handle_404( ); $this->register_globals( ); . . .
  • 33. WP::parse_request( )— Parses the URL using WP_Rewrite— Sets up query variables for WP_QueryWP::query_posts( ) { global $wp_the_query; $wp_the_query->query( $this->query_vars );}
  • 34. Boom.SELECT SQL_CALC_FOUND_ROWS wp_posts.*FROM wp_postsWHERE 1=1 AND wp_posts.post_type = post AND wp_posts.post_status = publishORDER BY wp_posts.post_date DESCLIMIT 0, 10
  • 35. 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;
  • 36. Before we get to the theme,we have your posts.Got it?
  • 37. Then why do we do this?query_posts( author=-5 );get_header( );while( have_posts( ) ) : the_post( );endwhile;get_footer( );
  • 38. Thats running 2* queries!One, the query WordPressthought we wanted.Two, this new one youreactually going to use.
  • 39. * Actually, WP_Querydoesnt run just one query.It usually runs four.
  • 40. 1. Get me my posts: SELECT SQL_CALC_FOUND_ROWS … FROM wp_posts LIMIT 0, 102. How many posts exist? SELECT FOUND_ROWS( )3. Get all metadata for these posts.4. Get all terms for these posts.
  • 41. (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,) );
  • 42. </aside>
  • 43. PROTIP‘Measure twice, cut once’is bad for performance.
  • 44. Other problems withquery_posts( )
  • 45. Pagination breaks.WordPress calculatedpaging using the query itdid, not the query you did.
  • 46. query_posts( array( author => -5, posts_per_page => 25,) );This will not work well.
  • 47. You easily mess up globals.This can break widgets andmore.
  • 48. query_posts( ) is bad.Do we agree?
  • 49. Introducing pre_get_postsclass WP_Query { . . . function &get_posts() { $this->parse_query(); // Huzzah! do_action_ref_array( pre_get_posts, array( &$this ) ); . . .
  • 50. 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 );
  • 51. Still with us?Good, ‘cause here’s wherethings get complicated.
  • 52. pre_get_posts fires for every postquery: — get_posts( ) — new WP_Query( ) — That random recent posts widget your clientinstalled without you knowing. — Everything.
  • 53. What if I just want it on themain query?
  • 54. $wp_the_query makes atriumphant return.
  • 55. 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 );
  • 56. Hmm. How does this work?$wp_the_query should never be modified. Itholds the main query, forever.$wp_query keeps a live reference to$wp_the_query, unless you usequery_posts( ).
  • 57. query_posts( author=-5 );while ( have_posts( ) ) : the_post( );endwhile;wp_reset_query( );
  • 58. query_posts( author=-5 );while ( have_posts( ) ) : the_post( );endwhile;wp_reset_query( );
  • 59. function query_posts( $query ) { // Break the reference to $wp_the_query unset( $wp_query ); $wp_query =& new WP_Query( $query ); return $wp_query;}
  • 60. query_posts( author=-5 );while ( have_posts( ) ) : the_post( );endwhile;wp_reset_query( );
  • 61. 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( );}
  • 62. 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.
  • 63. 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.
  • 64. What about pagetemplates?
  • 65. /* Template: My Template */query_posts( $query_string . &author=-5&posts_per_page=25 );get_header( );while ( have_posts( ) ) : the_post( );endwhile;
  • 66. 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 );
  • 67. Some LessonsEvery WP_Query object has methods thatmimic the global conditional tags.The global conditional tags apply to$wp_query, the main or current query.$wp_query is always the main query, unlessyou use query_posts( ). Restore it withwp_reset_query( ).
  • 68. And Finallypre_get_posts is a powerful and flexible hook.Just use it properly.Always check if youre modifying the mainquery using $query->is_main_query( )
  • 69. Thanks! Questions?@nacin