53
You Don’t Know Query WordPress London WordPress London May 16, 2012

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

  • Upload
    l3rady

  • View
    2.108

  • Download
    3

Embed Size (px)

DESCRIPTION

How to alter the main WordPress query the correct way. No more query_posts() pwease!by Scott Cariss of Philosophy DesignPhilosophy is a thought-led brand and digital consultancy based in London.

Citation preview

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

You Don’t Know Query

WordPress LondonWordPress LondonMay 16, 2012

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

Scott Cariss aka BradyScott Cariss aka Brady

d d l hil h i• Lead developer at Philosophy Design.

• Moderator at WordPress Answers (http://wordpress.stackexchange.com/)( p p g )

• WordPress plugin developer and enthusiast• WordPress plugin developer and enthusiast

@ hil h d iscott@philosophydesign@l3rady on Twitter

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

You Don’t Know QueryYou Don t Know Query

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

What do you know?What do you know?

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

Conditional TagsConditional Tags

is_author(), is_home(), etc.

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

Who has ever heard of query posts()?Who has ever heard of query_posts()?

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

Ways to queryWays to query

query_posts()new WP Query()new WP_Query()get_posts()

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

The loopThe loop

if( have_posts() )while( have posts() ):while( have_posts() ):the_post();

endwhile();endwhile();

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

What don’t you know?What don t you know?

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

Every query object has its own methods

is_author() is the same as calling$wp query‐>is author()$wp_query >is_author()

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

function is_author(){{global $wp_query;

return $wp query‐>is author();return $wp_query >is_author();}

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

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( ); 

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

h d ll hi likBut why do we call things likewp_reset_postdata( ) andp_ _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? 

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

What is the main query, and why should I care?

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

Let's dig inLet s dig in.

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

wp blog header phpwp‐blog‐header.php

// d h d b i// Load the WordPress bootstrap requiredirname( __FILE__ ) . '/wp‐load.php'; ( __ __ ) p p p

// Decide which template files to load// Decide which template files to loadABSPATH . WPINC . '/template‐loader.php'; 

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

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;

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

Quick lesson on PHP referencesQuick lesson on PHP references// R f i PHP t th i bl t t// References in PHP are a means to access the same variable content 

by different names.

$a = 4;$b =& $a;

// It means that $a and $b now point to the same content.

$b 2$b = 2;var_dump( $a ); // int(2)

$a = 6;var_dump( $b ); // int(6) 

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

So: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

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

wp blog header phpwp‐blog‐header.php

// d h d b i// Load the WordPress bootstrap requiredirname( __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'; 

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

What is that wp() call?What is that wp() call?

function wp( $query_vars = '' ){{global $wp; 

$wp‐>main( $query vars );$wp >main( $query_vars );} 

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

Holy $!@? what just happened?Holy $!@?, what just happened?

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

In the bootstrap:In the bootstrap:

$wp = new WP()

So there’s a wp() function, and a WP class.

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

class WPclass WP{...f ( )function main( ){ $this‐>init( );$this‐>parse_request( );$this‐>send_headers( );$this‐>query posts( );$ q y_p ( );$this‐>handle_404( );$this‐>register_globals( ); 

}}. . . 

}

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

class WPclass WP{...f ( )function main( ){ $this‐>init( );$this‐>parse_request( );$this‐>send_headers( );$this‐>query posts( );$ q y_p ( );$this‐>handle_404( );$this‐>register_globals( ); 

}}. . . 

}

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

WP t( )WP::parse_request( ) Parses the URL using WP_RewriteSets up query variables for WP_Query

WP::query_posts( ){global $wp_the_query;$wp the query‐>query( $this‐>query vars ); $ p_ _q y q y( $ q y_ );

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

What do we get?What do we get?

SELECT SQL_CALC_FOUND_ROWS wp posts.* FROMwp_posts.  FROM

wp_posts WHERE 1=1 AND wp_posts.post_type = 'post‘AND wp posts post status = 'publish' ORDERAND wp_posts.post_status =  publish  ORDER

BY wp_posts.post_date DESC LIMIT 0, 10 

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

wp blog header phpwp‐blog‐header.php

// d d// Load WordPressdirname( __FILE__ ) . '/wp‐load.php'; ( __ __ ) p p p

// Parse what to query and query it// Parse what to query, and query it. wp(); 

// Load the theme// Load the theme.ABSPATH . WPINC . '/template‐loader.php'; 

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

Before we get to the theme, we have your posts.

Are we clear so far?

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

Then why do we do this?Then why do we do this?

( ' h ' )query_posts( 'author=5' );get_header( );g _ ( )

while( have posts( ) ) :while( have_posts( ) ) : the_post( );

endwhile;

get_footer( ); 

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

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 useactually going to use.

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

* Actually, WP_Query doesn't run just onequery. It usually runs four.query. It usually runs four. 

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

1. Get me my posts: SELECTSQL_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 posts4. Pull down all terms for these posts. 

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

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 ); 

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

We can modify query variables in mid air:

function brady_filter_out_author( $qvs ){{if( ! Isset( $qvs[‘author’] ) )$qvs[‘author’] = ‘‐5’;

return $qvs;}

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

Powerful but lacks contextPowerful, but lacks context.

Problems:

1. Conditional tags don’t work yet.

2 Only works on the main query2. Only works on the main query.

3. WP_Query is way cooler.

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

Introducing pre get postsIntroducing pre_get_postsl WP Qclass WP_Query{ . . .function &get_posts(){ {$this‐>parse_query(); // OMG! Conditional tags are available!!do_action_ref_array( 'pre_get_posts', array( &$this ) ); 

}. . . 

}

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

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' ); 

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

Still with us?Still with us?

Good ‘cause here’s where things get hairy.

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

‘ ’ fi f h i l‘request’ fires for the main query only.

‘pre_get_posts’ fires for every post query:

• get_posts()• new WP_Query()• That random recent posts widgetThat random recent posts widget.• Everything.

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

What if I just want it on themain query?

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

$wp_the_query makes atriumphant return.

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

Main query only!Main query only!

f i b d l h ( $ )function brady_alter_home( $query ){{if ( $query‐>is_home( ) &&

$wp the query === $query )$wp_the_query === $query ) $query‐>set( 'author', '‐5' );

}add action( 'pre get posts'add_action(  pre_get_posts , ‘brady_alter_home' );

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

Hmm How does this work?Hmm. How does this work?

$wp_the_query should never be modified. It holds the main query, forever. q y

$ k li f$wp_query keeps a live reference to $wp_the_query, unless you use query_posts(). 

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

query_posts( 'author=‐5' ); while ( have posts( ) ) :while ( have_posts( ) ) : the_post( );

endwhile;wp reset query( );wp_reset_query( ); 

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

l WP Qclass WP_Query{ . . . function &query_posts( $query ){ // Break the reference to $wp the query// Break the reference to $wp_the_queryunset( $wp_query ); $wp_query =& new WP_Query( $query ); ...

}...

}

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

query_posts( 'author=‐5' ); while ( have posts( ) ) :while ( have_posts( ) ) : the_post( );

endwhile;wp reset query( );wp_reset_query( ); 

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

class WP Queryclass WP_Query{. . .f ( )function wp_reset_query( ){ // Restore the reference to $wp_the_queryunset( $wp_query );$wp_query =& $wp_the_query; // Reset the globals, too.// g ,wp_reset_postdata( );. . . 

}}....

}

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

Calling the_post( )? wp_reset_query( ) will reset $wp_query and and the globals. p_q y g

C lli $ h ( )?Calling $my_query‐>the_post( )? wp_reset_postdata( ) will reset the globals. 

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

Since WordPress 3 3!Since WordPress 3.3!

Rather than: $wp the query === $other query object$wp_the_query  $other_query_object

You‘re able to call: $other query object‐>is main query( )$other_query_object >is_main_query( ) 

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

Some LessonsSome Lessons

Every WP_Query object has methods that mimic the global conditional tags.g g

Th l b l di i l l $The global conditional tags apply to $wp_query, the main or current query. 

$ i l th i l$wp_query is always the main query, unless you use query_posts( ). Restore it with wp_reset_query( ).

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

And finallyAnd finally

request is a nice hook. pre_get_posts is more powerful and flexible. Just use it properly. p p p y

Al h k if ' dif i h iAlways check if you're modifying the main query using $query‐>is_main_query( ) 

$ $ th b f 3 3$query === $wp_the_query before 3.3

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

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.