• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
WordPress London 16 May 2012 - You don’t know query
 

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

on

  • 1,964 views

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

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.

Statistics

Views

Total Views
1,964
Views on SlideShare
1,962
Embed Views
2

Actions

Likes
2
Downloads
6
Comments
2

2 Embeds 2

https://si0.twimg.com 1
http://twitter.com 1

Accessibility

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

12 of 2 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

    • 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 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
    • 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(); endwhile();
    • 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 author()
    • 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( ) ) :while ( $my query‐>have posts( ) ) : $my_query‐>the_post( ); endwhile;wp_reset_postdata( ); 
    • 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? 
    • 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 idirname( __FILE__ ) . /wp‐load.php;  ( __ __ ) p p p// Decide which template files to load// Decide which template files to loadABSPATH . WPINC . /template‐loader.php; 
    • 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;
    • 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) 
    • 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 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; 
    • What is that wp() call? What is that wp() call?function wp( $query_vars =  ){ global $wp;  $wp >main( $query_vars $wp‐>main( $query vars );} 
    • 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( ); $this‐>send_headers( ); $ $this‐>query posts( ); q y_p ( ); $this‐>handle_404( ); $this‐>register_globals( );  } . . . }
    • 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( );  } . . . }
    • 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_ );} 
    • 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 
    • 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; 
    • 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( ); ()while( have_posts( ) ) : while( have posts( ) ) : the_post( );endwhile;get_footer( ); 
    • 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
    • * 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 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
    • 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 ); 
    • We can modify query variables in mid  air:function brady_filter_out_author( $qvs ){ if( ! Isset( $qvs[‘author’] ) ) $qvs[‘author’] = ‘‐5’; return $qvs;}
    • 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.
    • 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 ) );  } . . . }
    • 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 ); 
    • 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:• get_posts()• new WP_Query()• That random recent posts widget. That random recent posts widget• Everything.
    • 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 ( $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 );
    • 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(). 
    • query_posts( author=‐5 ); while ( have_posts( ) ) : while ( have posts( ) ) : the_post( );endwhile;wp_reset_query( ); wp reset query( );
    • 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 );  ... } ...}
    • query_posts( author=‐5 ); while ( have_posts( ) ) : while ( have posts( ) ) : the_post( );endwhile;wp_reset_query( ); wp reset query( );
    • 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( ); . . .  } ....}
    • 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. 
    • 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( )
    • 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( ).
    • 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
    • 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.