SlideShare une entreprise Scribd logo
1  sur  61
Télécharger pour lire hors ligne
WordCamp Portland 2011
September 17, 2011
Andrew Nacin
Core Developer of WordPress
Tech Ninja at Audrey Capital
nacin@wordpress.org
@nacin on Twitter
You Don't Know Query
What do you know?
Conditional Tags


is_author( ), is_home( ), etc.
Who has ever heard of
query_posts( )?
Ways to query

query_posts( )
new WP_Query( )
get_posts( )
The loop

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

  endwhile( );
What don't you know?
Every query object has its
own methods
is_author( ) is the same as calling
$wp_query->is_author( )
function is_author( ) {
  global $wp_query;

    return $wp_query->is_author( );
}
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( );
But why do we call things like
wp_reset_postdata( ) and
wp_reset_query( )?

What about using query_posts( )?

How can you alter a query? What
about the main query?
What is the main query,
and why should I care?
Let's dig in.
wp-blog-header.php
// Load the WordPress bootstrap
require dirname( __FILE__ ) . '/wp-load.php';

// Do magic
wp();

// Decide which template files to load
ABSPATH . WPINC . '/template-loader.php';
Let's look in the bootstrap:

$wp_the_query = new WP_Query();
$wp_query =& $wp_the_query;
Quick lesson on PHP references
$a = 4;
$b =& $a;
$b = 2;
var_dump( $a ); // int(2)
$a = 6;
var_dump( $b ); // int(6)
So:
So the real main query is in
$wp_the_query.

And a live copy of it is stored in
$wp_query.
wp-blog-header.php
// Load the WordPress bootstrap
require dirname( __FILE__ ) . '/wp-load.php';

// Do magic
wp();

// Decide which template files to load
ABSPATH . WPINC . '/template-loader.php';
wp-blog-header.php
// Load the WordPress bootstrap
require dirname( __FILE__ ) . '/wp-load.php';

// Do magic
wp( );

// Decide which template files to load
ABSPATH . WPINC . '/template-loader.php';
What is that wp( ) call?

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

    $wp->main( $query_vars );
}
Holy $!@?, what just
happened?
In the bootstrap:

$wp = new WP( );

So there's a wp( ) function,
and a WP class.
class WP {
    . . .
    function main( ) {
        $this->init( );
        $this->parse_request( );
        $this->send_headers( );
        $this->query_posts( );
        $this->handle_404( );
        $this->register_globals( );
   . . .
class WP {
    . . .
    function main( ) {
        $this->init( );
        $this->parse_request( );
        $this->send_headers( );
        $this->query_posts( );
        $this->handle_404( );
        $this->register_globals( );
   . . .
WP::parse_request( )
— Parses the URL using WP_Rewrite
— Sets up query variables for WP_Query

WP::query_posts( ) {
  global $wp_the_query;
  $wp_the_query->query( $this->query_vars );
}
Boom.
SELECT SQL_CALC_FOUND_ROWS
  wp_posts.*
FROM wp_posts
WHERE 1=1
  AND wp_posts.post_type = 'post'
  AND wp_posts.post_status = 'publish'
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
wp-blog-header.php

// Load WordPress.
require dirname(__FILE__) . '/wp-load.php';

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

// Load the theme.
ABSPATH . WPINC . '/template-loader.php';
Before we get to the theme,
we have your posts.

Got it?
Then why do we do this?

query_posts( 'author=5' );
get_header( );
while( have_posts( ) ) :
  the_post( );
endwhile;
get_footer( );
That's running 2* queries!

One, the query WordPress
thought we wanted.

Two, this new one you're
actually going to use.
* Actually, WP_Query
doesn't run just one 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?
     SELECT FOUND_ROWS()
3. Slurp all metadata for these posts.
4. Slurp all terms for these posts.
PROTIP
‘Measure twice, cut once’
is bad for performance.
(A note, 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,
) );
So. Instead of this:

query_posts( 'author=5' );
get_header( );
while ( have_posts( ) ) :
  the_post( );
endwhile;
get_footer( );
We can use this:

// In WP::parse_request()

$this->query_vars =
   apply_filters( 'request', $this->query_vars );
We can modify query
variables in mid air:
function nacin_filter_out_author( $qvs ) {
  if ( ! isset( $qvs['author'] ) )
          $qvs['author'] = '-5';
  return $qvs;
}
Powerful, but lacks context.
Powerful, but lacks context.

Problem 1: Conditional tags don't work yet.
Powerful, but lacks context.

Problem 1: Conditional tags don't work yet.

Problem 2: Only works on the main query.
Powerful, but lacks context.

Problem 1: Conditional tags don't work yet.

Problem 2: Only works on the main query.

Problem 3: WP_Query is waaay cooler.
Introducing pre_get_posts
class WP_Query {
   . . .
   function &get_posts() {
       $this->parse_query();
       // Huzzah! Conditional tags are available.
       do_action_ref_array( 'pre_get_posts',
          array( &$this ) );
   . . .
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' );
Still with us?


Good, ‘cause here’s where
things get hairy.
'request' fires for the main query only.

'pre_get_posts' fires for every post query:
— get_posts()
— new WP_Query()
— 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!

function nacin_alter_home ( $query ) {
  if ( $wp_the_query === $query
             && $query->is_home() )
                  $query->set( 'author', '-5' );
}
add_action( 'pre_get_posts', 'nacin_alter_home' );
Hmm. How does this work?

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

$wp_query keeps a live reference to
$wp_the_query, unless you use query_posts().
query_posts( 'author=-5' );
while ( have_posts( ) ) :
  the_post( );
endwhile;
wp_reset_query( );
query_posts( 'author=-5' );
while ( have_posts( ) ) :
  the_post( );
endwhile;
wp_reset_query( );
class WP_Query {
   . . .
   function &query_posts( $query ) {
         // Break the reference to $wp_the_query
         unset( $wp_query );
         $wp_query =& new WP_Query( $query );
         . . .
query_posts( 'author=-5' );
while ( have_posts( ) ) :
  the_post( );
endwhile;
wp_reset_query( );
class WP_Query {
   . . .
       function wp_reset_query( ) {
           // Restore the reference to
$wp_the_query
           unset( $wp_query );
           $wp_query =& $wp_the_query;
       // Reset the globals, too.
           wp_reset_postdata( );
       . . .
Calling the_post( )?
  wp_reset_query( ) will reset $wp_query
  and and the globals.

Calling $my_query->the_post( )?
  wp_reset_postdata( ) will reset the globals.
New thing for core in 3.3!
Rather than:
     $wp_the_query === $other_query_object
	
  
You'll be able to call:
     $other_query_object->is_main_query( )
	
  
is_main_query( ), the function, will act on
$wp_query, like any other conditional tag.
Some Lessons
Every WP_Query object has methods that
mimic the global conditional tags.

The global conditional tags apply to
$wp_query, the main or current query.

$wp_query is always the main query, unless
you use query_posts( ). Restore it with
wp_reset_query( ).
And Finally
request is a nice hook. pre_get_posts is more
powerful and flexible. Just use it properly.

Always check if you're modifying the main query
using $query === $wp_the_query

$query->is_main_query( ) in 3.3!
Thanks! Questions?


@nacin

Contenu connexe

Tendances

Plsql task answers
Plsql task answersPlsql task answers
Plsql task answers
Nawaz Sk
 

Tendances (20)

Desenvolvimento de um CRUD utilizando Stored Procedure
Desenvolvimento de um CRUD utilizando Stored ProcedureDesenvolvimento de um CRUD utilizando Stored Procedure
Desenvolvimento de um CRUD utilizando Stored Procedure
 
PHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object CalisthenicsPHP for Adults: Clean Code and Object Calisthenics
PHP for Adults: Clean Code and Object Calisthenics
 
Node.js File system & Streams
Node.js File system & StreamsNode.js File system & Streams
Node.js File system & Streams
 
Packages - PL/SQL
Packages - PL/SQLPackages - PL/SQL
Packages - PL/SQL
 
Php string function
Php string function Php string function
Php string function
 
Novidades do Java 8
Novidades do Java 8Novidades do Java 8
Novidades do Java 8
 
Pigeonhole sort
Pigeonhole sortPigeonhole sort
Pigeonhole sort
 
Kotlin Coroutines in Practice @ KotlinConf 2018
Kotlin Coroutines in Practice @ KotlinConf 2018Kotlin Coroutines in Practice @ KotlinConf 2018
Kotlin Coroutines in Practice @ KotlinConf 2018
 
Plsql task answers
Plsql task answersPlsql task answers
Plsql task answers
 
Sql Functions And Procedures
Sql Functions And ProceduresSql Functions And Procedures
Sql Functions And Procedures
 
Presentation slides of Sequence Query Language (SQL)
Presentation slides of Sequence Query Language (SQL)Presentation slides of Sequence Query Language (SQL)
Presentation slides of Sequence Query Language (SQL)
 
Java AWT and Java FX
Java AWT and Java FXJava AWT and Java FX
Java AWT and Java FX
 
Packages in PL/SQL
Packages in PL/SQLPackages in PL/SQL
Packages in PL/SQL
 
Class and Objects in PHP
Class and Objects in PHPClass and Objects in PHP
Class and Objects in PHP
 
MySQL Basics
MySQL BasicsMySQL Basics
MySQL Basics
 
Oracle - Program with PL/SQL - Lession 01
Oracle - Program with PL/SQL - Lession 01Oracle - Program with PL/SQL - Lession 01
Oracle - Program with PL/SQL - Lession 01
 
Procedure and Functions in pl/sql
Procedure and Functions in pl/sqlProcedure and Functions in pl/sql
Procedure and Functions in pl/sql
 
Aggregate functions
Aggregate functionsAggregate functions
Aggregate functions
 
API Design - 3rd Edition
API Design - 3rd EditionAPI Design - 3rd Edition
API Design - 3rd Edition
 
Java Hello World Program
Java Hello World ProgramJava Hello World Program
Java Hello World Program
 

Similaire à You Don't Know Query - WordCamp Portland 2011

You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012
l3rady
 
The Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the QueryThe Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the Query
Chris Olbekson
 

Similaire à You Don't Know Query - WordCamp Portland 2011 (20)

You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012
 
WordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryWordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know query
 
Wp query
Wp queryWp query
Wp query
 
The Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the QueryThe Query the Whole Query and Nothing but the Query
The Query the Whole Query and Nothing but the Query
 
WordPress Queries - the right way
WordPress Queries - the right wayWordPress Queries - the right way
WordPress Queries - the right way
 
Getting Creative with WordPress Queries
Getting Creative with WordPress QueriesGetting Creative with WordPress Queries
Getting Creative with WordPress Queries
 
Getting Creative with WordPress Queries, Again
Getting Creative with WordPress Queries, AgainGetting Creative with WordPress Queries, Again
Getting Creative with WordPress Queries, Again
 
WP_Query, pre_get_posts, and eliminating query_posts()
WP_Query, pre_get_posts, and eliminating query_posts()WP_Query, pre_get_posts, and eliminating query_posts()
WP_Query, pre_get_posts, and eliminating query_posts()
 
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0
 
Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018
 
You code sucks, let's fix it
You code sucks, let's fix itYou code sucks, let's fix it
You code sucks, let's fix it
 
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
 
Custom Database Queries in WordPress
Custom Database Queries in WordPressCustom Database Queries in WordPress
Custom Database Queries in WordPress
 
WordPress Kitchen 2014 - Александр Стриха: Кеширование в WordPress
WordPress Kitchen 2014 - Александр Стриха: Кеширование в WordPress WordPress Kitchen 2014 - Александр Стриха: Кеширование в WordPress
WordPress Kitchen 2014 - Александр Стриха: Кеширование в WordPress
 

Plus de andrewnacin

Plus de andrewnacin (17)

Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ...
Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ...Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ...
Challenges Building the WordPress REST API (API Strategy & Practice, Chicago ...
 
WordCamp Netherlands 2012: WordPress in 2012
WordCamp Netherlands 2012: WordPress in 2012WordCamp Netherlands 2012: WordPress in 2012
WordCamp Netherlands 2012: WordPress in 2012
 
WordCamp SF 2011: Debugging in WordPress
WordCamp SF 2011: Debugging in WordPressWordCamp SF 2011: Debugging in WordPress
WordCamp SF 2011: Debugging in WordPress
 
WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...
WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...
WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Mul...
 
Open Source (and you can too) - 2011 Teens in Tech Conference
Open Source (and you can too) - 2011 Teens in Tech ConferenceOpen Source (and you can too) - 2011 Teens in Tech Conference
Open Source (and you can too) - 2011 Teens in Tech Conference
 
WordCamp Columbus 2011 - What's Next for WordPress
WordCamp Columbus 2011 - What's Next for WordPressWordCamp Columbus 2011 - What's Next for WordPress
WordCamp Columbus 2011 - What's Next for WordPress
 
TEDxYouth@DowntownDC
TEDxYouth@DowntownDCTEDxYouth@DowntownDC
TEDxYouth@DowntownDC
 
Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)Best Practices in Plugin Development (WordCamp Seattle)
Best Practices in Plugin Development (WordCamp Seattle)
 
Ask Not What WordPress Can Do For You (Ignite - WordCamp Seattle)
Ask Not What WordPress Can Do For You (Ignite - WordCamp Seattle)Ask Not What WordPress Can Do For You (Ignite - WordCamp Seattle)
Ask Not What WordPress Can Do For You (Ignite - WordCamp Seattle)
 
Hidden Features (WordPress DC)
Hidden Features (WordPress DC)Hidden Features (WordPress DC)
Hidden Features (WordPress DC)
 
Lightning Talk: Mistakes (WordCamp Phoenix 2011)
Lightning Talk: Mistakes (WordCamp Phoenix 2011)Lightning Talk: Mistakes (WordCamp Phoenix 2011)
Lightning Talk: Mistakes (WordCamp Phoenix 2011)
 
WordPress at Web Content Mavens (Jan. 2011)
WordPress at Web Content Mavens (Jan. 2011)WordPress at Web Content Mavens (Jan. 2011)
WordPress at Web Content Mavens (Jan. 2011)
 
WordPress 3.1 at DC PHP
WordPress 3.1 at DC PHPWordPress 3.1 at DC PHP
WordPress 3.1 at DC PHP
 
What's Next for WordPress at WordCamp Netherlands
What's Next for WordPress at WordCamp NetherlandsWhat's Next for WordPress at WordCamp Netherlands
What's Next for WordPress at WordCamp Netherlands
 
What's Next for WordPress: WordCamp Birmingham 2010
What's Next for WordPress: WordCamp Birmingham 2010What's Next for WordPress: WordCamp Birmingham 2010
What's Next for WordPress: WordCamp Birmingham 2010
 
WordPress 3.0 at DC PHP
WordPress 3.0 at DC PHPWordPress 3.0 at DC PHP
WordPress 3.0 at DC PHP
 
Advanced and Hidden WordPress APIs
Advanced and Hidden WordPress APIsAdvanced and Hidden WordPress APIs
Advanced and Hidden WordPress APIs
 

Dernier

Dernier (20)

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 

You Don't Know Query - WordCamp Portland 2011

  • 2. Andrew Nacin Core Developer of WordPress Tech Ninja at Audrey Capital nacin@wordpress.org @nacin on Twitter
  • 4. What do you know?
  • 6. Who has ever heard of query_posts( )?
  • 7. Ways to query query_posts( ) new WP_Query( ) get_posts( )
  • 8. The loop if ( have_posts( ) ) while ( have_posts( ) ) : the_post( ); endwhile( );
  • 10. Every query object has its own methods is_author( ) is the same as calling $wp_query->is_author( )
  • 11. function is_author( ) { global $wp_query; return $wp_query->is_author( ); }
  • 12. 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( );
  • 13. But why do we call things like wp_reset_postdata( ) and wp_reset_query( )? What about using query_posts( )? How can you alter a query? What about the main query?
  • 14. What is the main query, and why should I care?
  • 16. wp-blog-header.php // Load the WordPress bootstrap require dirname( __FILE__ ) . '/wp-load.php'; // Do magic wp(); // Decide which template files to load ABSPATH . WPINC . '/template-loader.php';
  • 17. Let's look in the bootstrap: $wp_the_query = new WP_Query(); $wp_query =& $wp_the_query;
  • 18. Quick lesson on PHP references $a = 4; $b =& $a; $b = 2; var_dump( $a ); // int(2) $a = 6; var_dump( $b ); // int(6)
  • 19. So: So the real main query is in $wp_the_query. And a live copy of it is stored in $wp_query.
  • 20. wp-blog-header.php // Load the WordPress bootstrap require dirname( __FILE__ ) . '/wp-load.php'; // Do magic wp(); // Decide which template files to load ABSPATH . WPINC . '/template-loader.php';
  • 21. wp-blog-header.php // Load the WordPress bootstrap require dirname( __FILE__ ) . '/wp-load.php'; // Do magic wp( ); // Decide which template files to load ABSPATH . WPINC . '/template-loader.php';
  • 22. What is that wp( ) call? function wp( $query_vars = '' ) { global $wp; $wp->main( $query_vars ); }
  • 23. Holy $!@?, what just happened?
  • 24. In the bootstrap: $wp = new WP( ); So there's a wp( ) function, and a WP class.
  • 25. class WP { . . . function main( ) { $this->init( ); $this->parse_request( ); $this->send_headers( ); $this->query_posts( ); $this->handle_404( ); $this->register_globals( ); . . .
  • 26. class WP { . . . function main( ) { $this->init( ); $this->parse_request( ); $this->send_headers( ); $this->query_posts( ); $this->handle_404( ); $this->register_globals( ); . . .
  • 27. WP::parse_request( ) — Parses the URL using WP_Rewrite — Sets up query variables for WP_Query WP::query_posts( ) { global $wp_the_query; $wp_the_query->query( $this->query_vars ); }
  • 28. Boom. SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND wp_posts.post_status = 'publish' ORDER BY wp_posts.post_date DESC LIMIT 0, 10
  • 29. wp-blog-header.php // Load WordPress. require dirname(__FILE__) . '/wp-load.php'; // Parse what to query, and query it. wp(); // Load the theme. ABSPATH . WPINC . '/template-loader.php';
  • 30. Before we get to the theme, we have your posts. Got it?
  • 31. Then why do we do this? query_posts( 'author=5' ); get_header( ); while( have_posts( ) ) : the_post( ); endwhile; get_footer( );
  • 32. That's running 2* queries! One, the query WordPress thought we wanted. Two, this new one you're actually going to use.
  • 33. * Actually, WP_Query doesn't run just one query. It usually runs four.
  • 34. 1. Get me my posts: SELECT SQL_CALC_FOUND_ROWS … FROM wp_posts LIMIT 0, 10 2. How many posts exist? SELECT FOUND_ROWS() 3. Slurp all metadata for these posts. 4. Slurp all terms for these posts.
  • 35. PROTIP ‘Measure twice, cut once’ is bad for performance.
  • 36. (A note, 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, ) );
  • 37. So. Instead of this: query_posts( 'author=5' ); get_header( ); while ( have_posts( ) ) : the_post( ); endwhile; get_footer( );
  • 38. We can use this: // In WP::parse_request() $this->query_vars = apply_filters( 'request', $this->query_vars );
  • 39. We can modify query variables in mid air: function nacin_filter_out_author( $qvs ) { if ( ! isset( $qvs['author'] ) ) $qvs['author'] = '-5'; return $qvs; }
  • 41. Powerful, but lacks context. Problem 1: Conditional tags don't work yet.
  • 42. Powerful, but lacks context. Problem 1: Conditional tags don't work yet. Problem 2: Only works on the main query.
  • 43. Powerful, but lacks context. Problem 1: Conditional tags don't work yet. Problem 2: Only works on the main query. Problem 3: WP_Query is waaay cooler.
  • 44. Introducing pre_get_posts class WP_Query { . . . function &get_posts() { $this->parse_query(); // Huzzah! Conditional tags are available. do_action_ref_array( 'pre_get_posts', array( &$this ) ); . . .
  • 45. 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' );
  • 46. Still with us? Good, ‘cause here’s where things get hairy.
  • 47. 'request' fires for the main query only. 'pre_get_posts' fires for every post query: — get_posts() — new WP_Query() — That random recent posts widget. — Everything.
  • 48. What if I just want it on the main query?
  • 50. Main query only! function nacin_alter_home ( $query ) { if ( $wp_the_query === $query && $query->is_home() ) $query->set( 'author', '-5' ); } add_action( 'pre_get_posts', 'nacin_alter_home' );
  • 51. Hmm. How does this work? $wp_the_query should never be modified. It holds the main query, forever. $wp_query keeps a live reference to $wp_the_query, unless you use query_posts().
  • 52. query_posts( 'author=-5' ); while ( have_posts( ) ) : the_post( ); endwhile; wp_reset_query( );
  • 53. query_posts( 'author=-5' ); while ( have_posts( ) ) : the_post( ); endwhile; wp_reset_query( );
  • 54. class WP_Query { . . . function &query_posts( $query ) { // Break the reference to $wp_the_query unset( $wp_query ); $wp_query =& new WP_Query( $query ); . . .
  • 55. query_posts( 'author=-5' ); while ( have_posts( ) ) : the_post( ); endwhile; wp_reset_query( );
  • 56. class WP_Query { . . . function wp_reset_query( ) { // Restore the reference to $wp_the_query unset( $wp_query ); $wp_query =& $wp_the_query; // Reset the globals, too. wp_reset_postdata( ); . . .
  • 57. Calling the_post( )? wp_reset_query( ) will reset $wp_query and and the globals. Calling $my_query->the_post( )? wp_reset_postdata( ) will reset the globals.
  • 58. New thing for core in 3.3! Rather than: $wp_the_query === $other_query_object   You'll be able to call: $other_query_object->is_main_query( )   is_main_query( ), the function, will act on $wp_query, like any other conditional tag.
  • 59. Some Lessons Every WP_Query object has methods that mimic the global conditional tags. The global conditional tags apply to $wp_query, the main or current query. $wp_query is always the main query, unless you use query_posts( ). Restore it with wp_reset_query( ).
  • 60. And Finally request is a nice hook. pre_get_posts is more powerful and flexible. Just use it properly. Always check if you're modifying the main query using $query === $wp_the_query $query->is_main_query( ) in 3.3!