WordCamp Pune 2013
Savita Soni, co-founder AmiWorks & chief-poet for WPoets
Twitter @savitas
Power of WP_Query
Ways to fetch posts & related data

•   query_posts()
•   new WP_Query()
•   get_posts()
•   $wpdb global db object
query_posts()
How query_posts() looks

query_posts( $args );
while ( have_posts() ) :
        the_post();
        //the_title(), the_ID(), the_permalink() etc..
endwhile;

// Reset Query
wp_reset_query();
new WP_Query()
How WP_Query() looks
// The Query
$the_query = new WP_Query( $args );

// The Loop
while ( $the_query->have_posts() ) :
        $the_query->the_post();
        echo '<li>' . get_the_title() . '</li>';
endwhile;
wp_reset_postdata();
get_posts()
How get_posts() looks

<?php
global $post;
$args = array( 'numberposts' => 5, 'offset'=> 1, 'category' => 1 );
$myposts = get_posts( $args );
        foreach( $myposts as $post ) :
                setup_postdata($post); ?>
                <li><a href="<?php the_permalink(); ?>">
                <?php the_title(); ?></a></li>
        <?php endforeach;
?>
This all we already know?
So lets see something which we may not know...
Conditional tags

is_author()
is_home()
is_archive()


we know this as well and use them frequently…
But have you seen this?

$wp_query = new WP_Query( $args );
$wp_query->is_author()
$wp_query->is_home()
$wp_query->is_archive()


Yes every query object has its own methods
so we can do this as well

$my_query = new WP_Query( $args );
while( $my_query->have_posts() ):
      $my_query->the_post();
      if( $my_query->is_author()){
            // do something for author
     }
endwhile;
wp_reset_postdata();
why we always needs to call

wp_reset_query()
wp_reset_postdata();


with query_posts() or WP_Query()
because when we do this

query_posts( 'cat=5');
while ( have_posts() ) :
       the_post();
       //the_title(), the_ID(), the_permalink() etc..
endwhile;


We have altered the main query...
How?
global $wp_query; //this is the main query object
Do anyone know this?
$wp_the_query

So the real main query object $wp_the_query
and $wp_query is the live copy of $wp_the_query
it is something like


$wp_the_query = new WP_Query();
$wp_query = &$wp_the_query;
when we call query_posts(), it works like this



function query_posts($query) {
      $GLOBALS['wp_query'] = new WP_Query();
      return $GLOBALS['wp_query']->query($query);
}
and when we call wp_reset_query()



function wp_reset_query() {
       $GLOBALS['wp_query'] = $GLOBALS['wp_the_query'];
       wp_reset_postdata();
}
how many query(s) get called when we call
WP_Query()?




Is it running only one query with your passed
arguments????
it is running 4 queries

1. Select SQL_CALC_FOUND_ROWS....FROM wp_posts
limit 0,10

2. Select FOUND_ROWS();

3. Get all metadata attached to these posts.

4. Get all terms for these posts.
off some arguments selectively

new WP_Query(
     array(
            'no_found_rows' => false,
            'update_post_meta_cache' => false,
            'update_post_term_cache' => false
     )
)
what if I need to modify the main query only?




Use pre_get_posts hook
function exclude_category( $query ) {
       $query->set( 'cat', '-1,-1347' );
}
add_action( 'pre_get_posts', 'exclude_category' );
Now problem with this...

it gets called for every post query
get_posts()
WP_Query()
query_posts()
what if I just need it for home page query?

now $wp_the_query object will help

function exclude_category( $query ) {
      global $wp_the_query;
      if( $wp_the_query == $query
             and $query->home()){
             $query->set( 'cat', '-1,-1347' );
      }
}
add_action( 'pre_get_posts', 'exclude_category' );
After WordPress 3.3 we have an awesome function

is_main_query()
So rather than writing

function exclude_category( $query ) {
      global $wp_the_query;
      //if( $wp_the_query == $query and $query->home())
      if( $query->is_main_query() and $query->home()) {
              $query->set( 'cat', '-1,-1347' );
}
Conclusion

 Try to avoid using query_posts()
 If query_posts() is used then reset it with
  wp_reset_query()
 Use pre_get_posts hook to alter main query &
  use it with is_main_query() condition tag
Thanks



Email: savita@amiworks.com
      Twitter: @savitas

Wp query

  • 1.
  • 2.
    Savita Soni, co-founderAmiWorks & chief-poet for WPoets Twitter @savitas
  • 3.
  • 4.
    Ways to fetchposts & related data • query_posts() • new WP_Query() • get_posts() • $wpdb global db object
  • 5.
  • 6.
    How query_posts() looks query_posts($args ); while ( have_posts() ) : the_post(); //the_title(), the_ID(), the_permalink() etc.. endwhile; // Reset Query wp_reset_query();
  • 7.
  • 8.
    How WP_Query() looks //The Query $the_query = new WP_Query( $args ); // The Loop while ( $the_query->have_posts() ) : $the_query->the_post(); echo '<li>' . get_the_title() . '</li>'; endwhile; wp_reset_postdata();
  • 9.
  • 10.
    How get_posts() looks <?php global$post; $args = array( 'numberposts' => 5, 'offset'=> 1, 'category' => 1 ); $myposts = get_posts( $args ); foreach( $myposts as $post ) : setup_postdata($post); ?> <li><a href="<?php the_permalink(); ?>"> <?php the_title(); ?></a></li> <?php endforeach; ?>
  • 11.
    This all wealready know?
  • 12.
    So lets seesomething which we may not know...
  • 13.
    Conditional tags is_author() is_home() is_archive() we knowthis as well and use them frequently…
  • 14.
    But have youseen this? $wp_query = new WP_Query( $args ); $wp_query->is_author() $wp_query->is_home() $wp_query->is_archive() Yes every query object has its own methods
  • 15.
    so we cando this as well $my_query = new WP_Query( $args ); while( $my_query->have_posts() ): $my_query->the_post(); if( $my_query->is_author()){ // do something for author } endwhile; wp_reset_postdata();
  • 16.
    why we alwaysneeds to call wp_reset_query() wp_reset_postdata(); with query_posts() or WP_Query()
  • 17.
    because when wedo this query_posts( 'cat=5'); while ( have_posts() ) : the_post(); //the_title(), the_ID(), the_permalink() etc.. endwhile; We have altered the main query...
  • 18.
    How? global $wp_query; //thisis the main query object Do anyone know this? $wp_the_query So the real main query object $wp_the_query and $wp_query is the live copy of $wp_the_query
  • 19.
    it is somethinglike $wp_the_query = new WP_Query(); $wp_query = &$wp_the_query;
  • 20.
    when we callquery_posts(), it works like this function query_posts($query) { $GLOBALS['wp_query'] = new WP_Query(); return $GLOBALS['wp_query']->query($query); }
  • 21.
    and when wecall wp_reset_query() function wp_reset_query() { $GLOBALS['wp_query'] = $GLOBALS['wp_the_query']; wp_reset_postdata(); }
  • 23.
    how many query(s)get called when we call WP_Query()? Is it running only one query with your passed arguments????
  • 24.
    it is running4 queries 1. Select SQL_CALC_FOUND_ROWS....FROM wp_posts limit 0,10 2. Select FOUND_ROWS(); 3. Get all metadata attached to these posts. 4. Get all terms for these posts.
  • 25.
    off some argumentsselectively new WP_Query( array( 'no_found_rows' => false, 'update_post_meta_cache' => false, 'update_post_term_cache' => false ) )
  • 26.
    what if Ineed to modify the main query only? Use pre_get_posts hook
  • 27.
    function exclude_category( $query) { $query->set( 'cat', '-1,-1347' ); } add_action( 'pre_get_posts', 'exclude_category' );
  • 28.
    Now problem withthis... it gets called for every post query get_posts() WP_Query() query_posts()
  • 29.
    what if Ijust need it for home page query? now $wp_the_query object will help function exclude_category( $query ) { global $wp_the_query; if( $wp_the_query == $query and $query->home()){ $query->set( 'cat', '-1,-1347' ); } } add_action( 'pre_get_posts', 'exclude_category' );
  • 30.
    After WordPress 3.3we have an awesome function is_main_query()
  • 31.
    So rather thanwriting function exclude_category( $query ) { global $wp_the_query; //if( $wp_the_query == $query and $query->home()) if( $query->is_main_query() and $query->home()) { $query->set( 'cat', '-1,-1347' ); }
  • 32.
    Conclusion  Try toavoid using query_posts()  If query_posts() is used then reset it with wp_reset_query()  Use pre_get_posts hook to alter main query & use it with is_main_query() condition tag
  • 33.