SlideShare a Scribd company logo
1 of 41
Download to read offline
Getting Crazy Creative
with WordPress Queries
Drew Jaynes
WordCamp Cape Town 2015
• Platform Engineer at 10up
• Docs Committer for WordPress core
• 4.2 Release Lead
• Developing with WordPress since 2009
• Slides: http://drewf.us/wcct
Hi, I’m Drew.
• Basics
• No-Nos
• Optimizations
• Creative Querying
Topics
Query Basics
The Loop
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
...
endwhile;
endif;
The Loop: Internals
if ( $wp_query->have_posts() ) :
while ( $wp_query->have_posts() ) :
$wp_query->the_post();
...
endwhile;
endif;
WP_Query
// Query for the 7 latest, published posts.
$query = new WP_Query( array(
'posts_per_page' => 7,
'post_status' => 'publish'
) );
WP_Query: SQL
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 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, 7
• WP_Query wrapper
• Defaults: Filter suppression
• Defaults: No sticky posts
• Defaults: No found rows
• Array of results vs WP_Query instance
get_posts()
get_posts()
// Query for the 7 latest, published posts.
$query = get_posts( array(
'posts_per_page' => 7,
'post_status' => 'publish'
) );
get_posts(): SQL
SELECT wp_posts.ID 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, 7
• Action, not a filter
• Fires before the query actually runs
• Use query methods intead of top-level functio
e.g. $query->is_main_query()
pre_get_posts
pre_get_posts
/**
* Display both posts and pages in the home loop.
*
* @param WP_Query $query Main WP_Query instance.
*/
function pages_in_main_query( $query ) {
if ( ! is_admin() && is_home() ) {
$query->query_vars['post_type'] = array( 'post', 'page' );
}
}
add_action( 'pre_get_posts', 'pages_in_main_query' );
pre_get_posts: Original SQL
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts
WHERE 1=1
AND wp_posts.post_type = 'post'
AND (
wp_posts.post_status = ‘publish'
OR wp_posts.post_status = ‘private'
)
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
pre_get_posts: SQL
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts
WHERE 1=1
AND wp_posts.post_type IN ( 'post', 'page' )
AND (
wp_posts.post_status = ‘publish'
OR wp_posts.post_status = ‘private'
)
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
No-Nos
• Completely overrides the main query
• Very few valid use cases
• Custom page template archives
query_posts()
query_posts()
query_posts( array(
'post_type' => ‘page’,
‘post_per_page' => 4
) );
posts_per_page
get_posts( array(
‘posts_per_page’ => -1,
‘posts_per_page’ => 100
) );
Optimization
• update_post_term_cache
• update_post_meta_cache
• no_found_rows
• fields
• posts_per_page
Optimizing WP_Query
Optimizing WP_Query
$query = new WP_Query( array(
'update_post_term_cache' => false,
'update_post_meta_cache' => false,
'posts_per_page' => 100,
'no_found_rows' => true,
'fields' => 'ids'
) );
Creative Querying
WP_Query
• posts_* filters
• pre_get_posts action
WP_Query hooks
WP_Query orderby
$posts = get_posts( array(
'posts_per_page' => 15,
'orderby' => array(
'post_date' => 'DESC',
'post_title' => 'ASC'
),
) );
WP_Query orderby: SQL
SELECT wp_posts.ID 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, wp_posts.post_title ASC
LIMIT 0, 15
• Available 4.2+
• Order by independent meta clauses
• WP_Meta_Query, WP_User_Query,
WP_Comment_Query
WP_Query orderby: meta clauses
WP_Query orderby: meta clauses
$posts = get_posts( array(
'meta_query' => array(
'relation' => 'AND',
'state_clause' => array(
'key' => 'state',
'value' => 'Colorado'
),
'city_clause' => array(
'key' => 'city',
'compare' => 'EXISTS'
)
),
'orderby' => array(
'state_clause' => 'ASC',
'city_clause' => 'DESC'
)
) );
WP_Query orderby: meta clauses
$posts = get_posts( array(
'meta_query' => array(
'relation' => 'AND',
'state_clause' => array(
'key' => 'state',
'value' => 'Colorado'
),
'city_clause' => array(
'key' => 'city',
'compare' => 'EXISTS'
)
),
'orderby' => array(
'state_clause' => 'ASC',
'city_clause' => 'DESC'
)
) );
WP_Query orderby: SQL
SELECT wp_posts.ID FROM wp_posts
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id )
WHERE 1=1
AND (
( wp_postmeta.meta_key = ‘state’
AND CAST( wp_postmeta.meta_value AS CHAR ) = ‘Colorado'
)
AND mt1.meta_key = ‘city'
)
AND wp_posts.post_type = 'post'
AND ( ( wp_posts.post_status = 'publish' ) )
GROUP BY wp_posts.ID
ORDER BY
CAST( mt1.meta_value AS CHAR ) ASC,
CAST( wp_postmeta.meta_value AS CHAR ) DESC
LIMIT 0, 5
WP_User_Query
WP_User_Query
// Query for users registered on a Tuesday.
$query = new WP_User_Query( array(
'date_query' => array(
array(
'column' => 'user_registered',
'dayofweek' => 3 // Tuesday
)
),
) );
Custom WP_Query Orderby
• Order results by a value in a custom table
• Adds an additional LEFT JOIN
WP_Query orderby with custom tables
Joining Custom Tables: JOIN
/**
* Join vote totals table to the 'books' custom post type query.
*
* @param string $join JOIN query clauses.
* @param WP_Query $query Current WP_Query instance.
* @return string The filtered JOIN clauses.
*/
function join_votes_table( $join, $query ) {
global $wpdb;
if ( ! is_admin() ) {
if ( isset( $query->query_vars['post_type'] )
&& 'books' == $query->query_vars[‘post_type']
) {
$votes = $wpdb->prefix . 'up_down_post_vote_totals';
$join .= "LEFT JOIN $votes ON $wpdb->posts.ID = $votes.post_id ";
}
}
return $join;
}
add_filter( 'posts_join', 'join_votes_table', 10, 2 );
Joining Custom Tables: ORDERBY
/**
* Order by vote totals descending, then post date descending.
*
* @param string $orderby ORDER BY query clauses.
* @param WP_Query $query Current WP_Query instance.
* @return string The filtered ORDER BY query clauses.
*/
function orderby_votes_and_date( $orderby, $query ) {
global $wpdb;
if ( ! is_admin() ) {
if ( isset( $query->query_vars['post_type'] )
&& 'books' == $query->query_vars[‘post_type']
) {
$votes = $wpdb->prefix . 'up_down_post_vote_totals';
$orderby = "$votes.vote_count_up DESC, $wpdb->posts.post_date DESC";
}
}
return $orderby;
}
add_filter( 'posts_orderby', 'orderby_votes_and_date', 10, 2 );
Joining Custom Tables: SQL
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts
WHERE 1=1
AND wp_posts.post_type = 'books'
AND ( wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private' )
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
Original SQL:
Joining Custom Tables: SQL
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts
LEFT JOIN wp_up_down_post_vote_totals
ON wp_posts.ID = wp_up_down_post_vote_totals.post_id
WHERE 1=1
AND wp_posts.post_type = 'books'
AND ( wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private' )
ORDER BY
wp_up_down_post_vote_totals.vote_count_up DESC,
wp_posts.post_date DESC
LIMIT 0, 10
SQL with the JOIN:
• WordPress Code Reference
• WP_Query Reference (Codex)
• Trunk wp-includes/
Resources
Questions?
Drew Jaynes | @DrewAPicture
Slides: http://drewf.us/wcct

More Related Content

What's hot

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()Erick Hitter
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Kris Wallsmith
 
Custom Database Queries in WordPress
Custom Database Queries in WordPressCustom Database Queries in WordPress
Custom Database Queries in WordPresstopher1kenobe
 
Let's write secure Drupal code! - Drupal Camp Poland 2019
Let's write secure Drupal code! - Drupal Camp Poland 2019Let's write secure Drupal code! - Drupal Camp Poland 2019
Let's write secure Drupal code! - Drupal Camp Poland 2019Balázs Tatár
 
Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019Balázs Tatár
 
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Balázs Tatár
 
Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019Balázs Tatár
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in OptimizationDavid Golden
 
Contributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter WilsonContributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter WilsonWordCamp Sydney
 
Assetic (Symfony Live Paris)
Assetic (Symfony Live Paris)Assetic (Symfony Live Paris)
Assetic (Symfony Live Paris)Kris Wallsmith
 
Image manipulation in WordPress 3.5
Image manipulation in WordPress 3.5Image manipulation in WordPress 3.5
Image manipulation in WordPress 3.5Marko Heijnen
 
11. CodeIgniter vederea unei singure inregistrari
11. CodeIgniter vederea unei singure inregistrari11. CodeIgniter vederea unei singure inregistrari
11. CodeIgniter vederea unei singure inregistrariRazvan Raducanu, PhD
 
The effective use of Django ORM
The effective use of Django ORMThe effective use of Django ORM
The effective use of Django ORMYaroslav Muravskyi
 
Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919Paul Bearne
 
Let's write secure Drupal code! Drupal MountainCamp 2019
Let's write secure Drupal code! Drupal MountainCamp 2019Let's write secure Drupal code! Drupal MountainCamp 2019
Let's write secure Drupal code! Drupal MountainCamp 2019Balázs Tatár
 
Refactor Dance - Puppet Labs 'Best Practices'
Refactor Dance - Puppet Labs 'Best Practices'Refactor Dance - Puppet Labs 'Best Practices'
Refactor Dance - Puppet Labs 'Best Practices'Gary Larizza
 
Forget about loops
Forget about loopsForget about loops
Forget about loopsDušan Kasan
 

What's hot (20)

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()
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
 
Custom Database Queries in WordPress
Custom Database Queries in WordPressCustom Database Queries in WordPress
Custom Database Queries in WordPress
 
Assetic (OSCON)
Assetic (OSCON)Assetic (OSCON)
Assetic (OSCON)
 
Let's write secure Drupal code! - Drupal Camp Poland 2019
Let's write secure Drupal code! - Drupal Camp Poland 2019Let's write secure Drupal code! - Drupal Camp Poland 2019
Let's write secure Drupal code! - Drupal Camp Poland 2019
 
Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019Let's write secure drupal code! - Drupal Camp Pannonia 2019
Let's write secure drupal code! - Drupal Camp Pannonia 2019
 
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
 
Week3 adb
Week3 adbWeek3 adb
Week3 adb
 
Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019Let's write secure Drupal code! DUG Belgium - 08/08/2019
Let's write secure Drupal code! DUG Belgium - 08/08/2019
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in Optimization
 
Contributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter WilsonContributing to WordPress Core - Peter Wilson
Contributing to WordPress Core - Peter Wilson
 
Assetic (Symfony Live Paris)
Assetic (Symfony Live Paris)Assetic (Symfony Live Paris)
Assetic (Symfony Live Paris)
 
Image manipulation in WordPress 3.5
Image manipulation in WordPress 3.5Image manipulation in WordPress 3.5
Image manipulation in WordPress 3.5
 
11. CodeIgniter vederea unei singure inregistrari
11. CodeIgniter vederea unei singure inregistrari11. CodeIgniter vederea unei singure inregistrari
11. CodeIgniter vederea unei singure inregistrari
 
Mentor Your Indexes
Mentor Your IndexesMentor Your Indexes
Mentor Your Indexes
 
The effective use of Django ORM
The effective use of Django ORMThe effective use of Django ORM
The effective use of Django ORM
 
Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919Childthemes ottawa-word camp-1919
Childthemes ottawa-word camp-1919
 
Let's write secure Drupal code! Drupal MountainCamp 2019
Let's write secure Drupal code! Drupal MountainCamp 2019Let's write secure Drupal code! Drupal MountainCamp 2019
Let's write secure Drupal code! Drupal MountainCamp 2019
 
Refactor Dance - Puppet Labs 'Best Practices'
Refactor Dance - Puppet Labs 'Best Practices'Refactor Dance - Puppet Labs 'Best Practices'
Refactor Dance - Puppet Labs 'Best Practices'
 
Forget about loops
Forget about loopsForget about loops
Forget about loops
 

Similar to Getting Creative with WordPress Queries

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 QueryChris Olbekson
 
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 queryl3rady
 
You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011andrewnacin
 
Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019Adam Tomat
 
Can WordPress really do that? A case study of vierderduer.no
Can WordPress really do that? A case study of vierderduer.noCan WordPress really do that? A case study of vierderduer.no
Can WordPress really do that? A case study of vierderduer.noMorten Rand-Hendriksen
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Working with WP_Query in WordPress
Working with WP_Query in WordPressWorking with WP_Query in WordPress
Working with WP_Query in WordPresstopher1kenobe
 
Becoming a better WordPress Developer
Becoming a better WordPress DeveloperBecoming a better WordPress Developer
Becoming a better WordPress DeveloperJoey Kudish
 
Why Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary ThingWhy Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary ThingChris Reynolds
 
WordPress as an application framework
WordPress as an application frameworkWordPress as an application framework
WordPress as an application frameworkDustin Filippini
 
Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)mpvanwinkle
 
WordPress 3.4 Theme Customizer
WordPress 3.4 Theme CustomizerWordPress 3.4 Theme Customizer
WordPress 3.4 Theme CustomizerChandra Maharzan
 
WordPress Café: Using WordPress as a Framework
WordPress Café: Using WordPress as a FrameworkWordPress Café: Using WordPress as a Framework
WordPress Café: Using WordPress as a FrameworkExove
 
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Mike Schinkel
 
WordPress for developers - phpday 2011
WordPress for developers -  phpday 2011WordPress for developers -  phpday 2011
WordPress for developers - phpday 2011Maurizio Pelizzone
 
DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7chuvainc
 
The Way to Theme Enlightenment
The Way to Theme EnlightenmentThe Way to Theme Enlightenment
The Way to Theme EnlightenmentAmanda Giles
 

Similar to Getting Creative with WordPress Queries (20)

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 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
 
You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011
 
Victoria wordpress
Victoria wordpressVictoria wordpress
Victoria wordpress
 
Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019
 
Can WordPress really do that? A case study of vierderduer.no
Can WordPress really do that? A case study of vierderduer.noCan WordPress really do that? A case study of vierderduer.no
Can WordPress really do that? A case study of vierderduer.no
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
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
 
Working with WP_Query in WordPress
Working with WP_Query in WordPressWorking with WP_Query in WordPress
Working with WP_Query in WordPress
 
Becoming a better WordPress Developer
Becoming a better WordPress DeveloperBecoming a better WordPress Developer
Becoming a better WordPress Developer
 
Why Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary ThingWhy Hacking WordPress Search Isn't Some Big Scary Thing
Why Hacking WordPress Search Isn't Some Big Scary Thing
 
WordPress as an application framework
WordPress as an application frameworkWordPress as an application framework
WordPress as an application framework
 
Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)Wordcamp Fayetteville Pods Presentation (PDF)
Wordcamp Fayetteville Pods Presentation (PDF)
 
WordPress 3.4 Theme Customizer
WordPress 3.4 Theme CustomizerWordPress 3.4 Theme Customizer
WordPress 3.4 Theme Customizer
 
WordPress Café: Using WordPress as a Framework
WordPress Café: Using WordPress as a FrameworkWordPress Café: Using WordPress as a Framework
WordPress Café: Using WordPress as a Framework
 
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
Hardcore URL Routing for WordPress - WordCamp Atlanta 2014 (PPT)
 
WordPress for developers - phpday 2011
WordPress for developers -  phpday 2011WordPress for developers -  phpday 2011
WordPress for developers - phpday 2011
 
DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7
 
The Way to Theme Enlightenment
The Way to Theme EnlightenmentThe Way to Theme Enlightenment
The Way to Theme Enlightenment
 

More from DrewAPicture

WordPress Development in a Modern PHP World
WordPress Development in a Modern PHP WorldWordPress Development in a Modern PHP World
WordPress Development in a Modern PHP WorldDrewAPicture
 
WordPress Development in a Modern PHP World
WordPress Development in a Modern PHP WorldWordPress Development in a Modern PHP World
WordPress Development in a Modern PHP WorldDrewAPicture
 
How to Win Friends and Influence WordPress Core
How to Win Friends and Influence WordPress CoreHow to Win Friends and Influence WordPress Core
How to Win Friends and Influence WordPress CoreDrewAPicture
 
Trying Out Tomorrow’s WordPress Today
Trying Out Tomorrow’s WordPress TodayTrying Out Tomorrow’s WordPress Today
Trying Out Tomorrow’s WordPress TodayDrewAPicture
 
It Takes a Village to Make WordPress
It Takes a Village to Make WordPressIt Takes a Village to Make WordPress
It Takes a Village to Make WordPressDrewAPicture
 
Setting Up WordPress: A NUX Case Study
Setting Up WordPress: A NUX Case StudySetting Up WordPress: A NUX Case Study
Setting Up WordPress: A NUX Case StudyDrewAPicture
 
Core Docs: Sentencing WordPress to 11-years-to-life
Core Docs: Sentencing WordPress to 11-years-to-lifeCore Docs: Sentencing WordPress to 11-years-to-life
Core Docs: Sentencing WordPress to 11-years-to-lifeDrewAPicture
 
Putting the (docs) Cart Before the (standards) Horse
Putting the (docs) Cart Before the (standards) HorsePutting the (docs) Cart Before the (standards) Horse
Putting the (docs) Cart Before the (standards) HorseDrewAPicture
 
There's a Filter For That
There's a Filter For ThatThere's a Filter For That
There's a Filter For ThatDrewAPicture
 
Customizer-ing Theme Options: A Visual Playground
Customizer-ing Theme Options: A Visual PlaygroundCustomizer-ing Theme Options: A Visual Playground
Customizer-ing Theme Options: A Visual PlaygroundDrewAPicture
 
Anatomy of the WordPress Loop
Anatomy of the WordPress LoopAnatomy of the WordPress Loop
Anatomy of the WordPress LoopDrewAPicture
 

More from DrewAPicture (11)

WordPress Development in a Modern PHP World
WordPress Development in a Modern PHP WorldWordPress Development in a Modern PHP World
WordPress Development in a Modern PHP World
 
WordPress Development in a Modern PHP World
WordPress Development in a Modern PHP WorldWordPress Development in a Modern PHP World
WordPress Development in a Modern PHP World
 
How to Win Friends and Influence WordPress Core
How to Win Friends and Influence WordPress CoreHow to Win Friends and Influence WordPress Core
How to Win Friends and Influence WordPress Core
 
Trying Out Tomorrow’s WordPress Today
Trying Out Tomorrow’s WordPress TodayTrying Out Tomorrow’s WordPress Today
Trying Out Tomorrow’s WordPress Today
 
It Takes a Village to Make WordPress
It Takes a Village to Make WordPressIt Takes a Village to Make WordPress
It Takes a Village to Make WordPress
 
Setting Up WordPress: A NUX Case Study
Setting Up WordPress: A NUX Case StudySetting Up WordPress: A NUX Case Study
Setting Up WordPress: A NUX Case Study
 
Core Docs: Sentencing WordPress to 11-years-to-life
Core Docs: Sentencing WordPress to 11-years-to-lifeCore Docs: Sentencing WordPress to 11-years-to-life
Core Docs: Sentencing WordPress to 11-years-to-life
 
Putting the (docs) Cart Before the (standards) Horse
Putting the (docs) Cart Before the (standards) HorsePutting the (docs) Cart Before the (standards) Horse
Putting the (docs) Cart Before the (standards) Horse
 
There's a Filter For That
There's a Filter For ThatThere's a Filter For That
There's a Filter For That
 
Customizer-ing Theme Options: A Visual Playground
Customizer-ing Theme Options: A Visual PlaygroundCustomizer-ing Theme Options: A Visual Playground
Customizer-ing Theme Options: A Visual Playground
 
Anatomy of the WordPress Loop
Anatomy of the WordPress LoopAnatomy of the WordPress Loop
Anatomy of the WordPress Loop
 

Recently uploaded

Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfInclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfTechSoup
 
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...Postal Advocate Inc.
 
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITY
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITYISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITY
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITYKayeClaireEstoconing
 
ENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choomENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choomnelietumpap1
 
Barangay Council for the Protection of Children (BCPC) Orientation.pptx
Barangay Council for the Protection of Children (BCPC) Orientation.pptxBarangay Council for the Protection of Children (BCPC) Orientation.pptx
Barangay Council for the Protection of Children (BCPC) Orientation.pptxCarlos105
 
Gas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptxGas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptxDr.Ibrahim Hassaan
 
Science 7 Quarter 4 Module 2: Natural Resources.pptx
Science 7 Quarter 4 Module 2: Natural Resources.pptxScience 7 Quarter 4 Module 2: Natural Resources.pptx
Science 7 Quarter 4 Module 2: Natural Resources.pptxMaryGraceBautista27
 
How to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERPHow to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERPCeline George
 
Earth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatEarth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatYousafMalik24
 
Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17Celine George
 
Influencing policy (training slides from Fast Track Impact)
Influencing policy (training slides from Fast Track Impact)Influencing policy (training slides from Fast Track Impact)
Influencing policy (training slides from Fast Track Impact)Mark Reed
 
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONTHEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONHumphrey A Beña
 
Judging the Relevance and worth of ideas part 2.pptx
Judging the Relevance  and worth of ideas part 2.pptxJudging the Relevance  and worth of ideas part 2.pptx
Judging the Relevance and worth of ideas part 2.pptxSherlyMaeNeri
 
Full Stack Web Development Course for Beginners
Full Stack Web Development Course  for BeginnersFull Stack Web Development Course  for Beginners
Full Stack Web Development Course for BeginnersSabitha Banu
 
Grade 9 Q4-MELC1-Active and Passive Voice.pptx
Grade 9 Q4-MELC1-Active and Passive Voice.pptxGrade 9 Q4-MELC1-Active and Passive Voice.pptx
Grade 9 Q4-MELC1-Active and Passive Voice.pptxChelloAnnAsuncion2
 
Proudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxProudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxthorishapillay1
 
What is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPWhat is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPCeline George
 
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...JhezDiaz1
 
How to Add Barcode on PDF Report in Odoo 17
How to Add Barcode on PDF Report in Odoo 17How to Add Barcode on PDF Report in Odoo 17
How to Add Barcode on PDF Report in Odoo 17Celine George
 

Recently uploaded (20)

Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdfInclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
Inclusivity Essentials_ Creating Accessible Websites for Nonprofits .pdf
 
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
 
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITY
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITYISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITY
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITY
 
ENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choomENGLISH6-Q4-W3.pptxqurter our high choom
ENGLISH6-Q4-W3.pptxqurter our high choom
 
Barangay Council for the Protection of Children (BCPC) Orientation.pptx
Barangay Council for the Protection of Children (BCPC) Orientation.pptxBarangay Council for the Protection of Children (BCPC) Orientation.pptx
Barangay Council for the Protection of Children (BCPC) Orientation.pptx
 
Gas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptxGas measurement O2,Co2,& ph) 04/2024.pptx
Gas measurement O2,Co2,& ph) 04/2024.pptx
 
Science 7 Quarter 4 Module 2: Natural Resources.pptx
Science 7 Quarter 4 Module 2: Natural Resources.pptxScience 7 Quarter 4 Module 2: Natural Resources.pptx
Science 7 Quarter 4 Module 2: Natural Resources.pptx
 
How to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERPHow to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERP
 
Earth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatEarth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice great
 
LEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptx
LEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptxLEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptx
LEFT_ON_C'N_ PRELIMS_EL_DORADO_2024.pptx
 
Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17
 
Influencing policy (training slides from Fast Track Impact)
Influencing policy (training slides from Fast Track Impact)Influencing policy (training slides from Fast Track Impact)
Influencing policy (training slides from Fast Track Impact)
 
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONTHEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
 
Judging the Relevance and worth of ideas part 2.pptx
Judging the Relevance  and worth of ideas part 2.pptxJudging the Relevance  and worth of ideas part 2.pptx
Judging the Relevance and worth of ideas part 2.pptx
 
Full Stack Web Development Course for Beginners
Full Stack Web Development Course  for BeginnersFull Stack Web Development Course  for Beginners
Full Stack Web Development Course for Beginners
 
Grade 9 Q4-MELC1-Active and Passive Voice.pptx
Grade 9 Q4-MELC1-Active and Passive Voice.pptxGrade 9 Q4-MELC1-Active and Passive Voice.pptx
Grade 9 Q4-MELC1-Active and Passive Voice.pptx
 
Proudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptxProudly South Africa powerpoint Thorisha.pptx
Proudly South Africa powerpoint Thorisha.pptx
 
What is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPWhat is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERP
 
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
ENGLISH 7_Q4_LESSON 2_ Employing a Variety of Strategies for Effective Interp...
 
How to Add Barcode on PDF Report in Odoo 17
How to Add Barcode on PDF Report in Odoo 17How to Add Barcode on PDF Report in Odoo 17
How to Add Barcode on PDF Report in Odoo 17
 

Getting Creative with WordPress Queries

  • 1. Getting Crazy Creative with WordPress Queries Drew Jaynes WordCamp Cape Town 2015
  • 2. • Platform Engineer at 10up • Docs Committer for WordPress core • 4.2 Release Lead • Developing with WordPress since 2009 • Slides: http://drewf.us/wcct Hi, I’m Drew.
  • 3. • Basics • No-Nos • Optimizations • Creative Querying Topics
  • 5. The Loop if ( have_posts() ) : while ( have_posts() ) : the_post(); ... endwhile; endif;
  • 6. The Loop: Internals if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post(); ... endwhile; endif;
  • 7. WP_Query // Query for the 7 latest, published posts. $query = new WP_Query( array( 'posts_per_page' => 7, 'post_status' => 'publish' ) );
  • 8. WP_Query: SQL SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 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, 7
  • 9. • WP_Query wrapper • Defaults: Filter suppression • Defaults: No sticky posts • Defaults: No found rows • Array of results vs WP_Query instance get_posts()
  • 10. get_posts() // Query for the 7 latest, published posts. $query = get_posts( array( 'posts_per_page' => 7, 'post_status' => 'publish' ) );
  • 11. get_posts(): SQL SELECT wp_posts.ID 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, 7
  • 12. • Action, not a filter • Fires before the query actually runs • Use query methods intead of top-level functio e.g. $query->is_main_query() pre_get_posts
  • 13. pre_get_posts /** * Display both posts and pages in the home loop. * * @param WP_Query $query Main WP_Query instance. */ function pages_in_main_query( $query ) { if ( ! is_admin() && is_home() ) { $query->query_vars['post_type'] = array( 'post', 'page' ); } } add_action( 'pre_get_posts', 'pages_in_main_query' );
  • 14. pre_get_posts: Original SQL SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND ( wp_posts.post_status = ‘publish' OR wp_posts.post_status = ‘private' ) ORDER BY wp_posts.post_date DESC LIMIT 0, 10
  • 15. pre_get_posts: SQL SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type IN ( 'post', 'page' ) AND ( wp_posts.post_status = ‘publish' OR wp_posts.post_status = ‘private' ) ORDER BY wp_posts.post_date DESC LIMIT 0, 10
  • 17. • Completely overrides the main query • Very few valid use cases • Custom page template archives query_posts()
  • 18. query_posts() query_posts( array( 'post_type' => ‘page’, ‘post_per_page' => 4 ) );
  • 19. posts_per_page get_posts( array( ‘posts_per_page’ => -1, ‘posts_per_page’ => 100 ) );
  • 21. • update_post_term_cache • update_post_meta_cache • no_found_rows • fields • posts_per_page Optimizing WP_Query
  • 22. Optimizing WP_Query $query = new WP_Query( array( 'update_post_term_cache' => false, 'update_post_meta_cache' => false, 'posts_per_page' => 100, 'no_found_rows' => true, 'fields' => 'ids' ) );
  • 25. • posts_* filters • pre_get_posts action WP_Query hooks
  • 26. WP_Query orderby $posts = get_posts( array( 'posts_per_page' => 15, 'orderby' => array( 'post_date' => 'DESC', 'post_title' => 'ASC' ), ) );
  • 27. WP_Query orderby: SQL SELECT wp_posts.ID 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, wp_posts.post_title ASC LIMIT 0, 15
  • 28. • Available 4.2+ • Order by independent meta clauses • WP_Meta_Query, WP_User_Query, WP_Comment_Query WP_Query orderby: meta clauses
  • 29. WP_Query orderby: meta clauses $posts = get_posts( array( 'meta_query' => array( 'relation' => 'AND', 'state_clause' => array( 'key' => 'state', 'value' => 'Colorado' ), 'city_clause' => array( 'key' => 'city', 'compare' => 'EXISTS' ) ), 'orderby' => array( 'state_clause' => 'ASC', 'city_clause' => 'DESC' ) ) );
  • 30. WP_Query orderby: meta clauses $posts = get_posts( array( 'meta_query' => array( 'relation' => 'AND', 'state_clause' => array( 'key' => 'state', 'value' => 'Colorado' ), 'city_clause' => array( 'key' => 'city', 'compare' => 'EXISTS' ) ), 'orderby' => array( 'state_clause' => 'ASC', 'city_clause' => 'DESC' ) ) );
  • 31. WP_Query orderby: SQL SELECT wp_posts.ID FROM wp_posts INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) INNER JOIN wp_postmeta AS mt1 ON ( wp_posts.ID = mt1.post_id ) WHERE 1=1 AND ( ( wp_postmeta.meta_key = ‘state’ AND CAST( wp_postmeta.meta_value AS CHAR ) = ‘Colorado' ) AND mt1.meta_key = ‘city' ) AND wp_posts.post_type = 'post' AND ( ( wp_posts.post_status = 'publish' ) ) GROUP BY wp_posts.ID ORDER BY CAST( mt1.meta_value AS CHAR ) ASC, CAST( wp_postmeta.meta_value AS CHAR ) DESC LIMIT 0, 5
  • 33. WP_User_Query // Query for users registered on a Tuesday. $query = new WP_User_Query( array( 'date_query' => array( array( 'column' => 'user_registered', 'dayofweek' => 3 // Tuesday ) ), ) );
  • 35. • Order results by a value in a custom table • Adds an additional LEFT JOIN WP_Query orderby with custom tables
  • 36. Joining Custom Tables: JOIN /** * Join vote totals table to the 'books' custom post type query. * * @param string $join JOIN query clauses. * @param WP_Query $query Current WP_Query instance. * @return string The filtered JOIN clauses. */ function join_votes_table( $join, $query ) { global $wpdb; if ( ! is_admin() ) { if ( isset( $query->query_vars['post_type'] ) && 'books' == $query->query_vars[‘post_type'] ) { $votes = $wpdb->prefix . 'up_down_post_vote_totals'; $join .= "LEFT JOIN $votes ON $wpdb->posts.ID = $votes.post_id "; } } return $join; } add_filter( 'posts_join', 'join_votes_table', 10, 2 );
  • 37. Joining Custom Tables: ORDERBY /** * Order by vote totals descending, then post date descending. * * @param string $orderby ORDER BY query clauses. * @param WP_Query $query Current WP_Query instance. * @return string The filtered ORDER BY query clauses. */ function orderby_votes_and_date( $orderby, $query ) { global $wpdb; if ( ! is_admin() ) { if ( isset( $query->query_vars['post_type'] ) && 'books' == $query->query_vars[‘post_type'] ) { $votes = $wpdb->prefix . 'up_down_post_vote_totals'; $orderby = "$votes.vote_count_up DESC, $wpdb->posts.post_date DESC"; } } return $orderby; } add_filter( 'posts_orderby', 'orderby_votes_and_date', 10, 2 );
  • 38. Joining Custom Tables: SQL SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'books' AND ( wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private' ) ORDER BY wp_posts.post_date DESC LIMIT 0, 10 Original SQL:
  • 39. Joining Custom Tables: SQL SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts LEFT JOIN wp_up_down_post_vote_totals ON wp_posts.ID = wp_up_down_post_vote_totals.post_id WHERE 1=1 AND wp_posts.post_type = 'books' AND ( wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private' ) ORDER BY wp_up_down_post_vote_totals.vote_count_up DESC, wp_posts.post_date DESC LIMIT 0, 10 SQL with the JOIN:
  • 40. • WordPress Code Reference • WP_Query Reference (Codex) • Trunk wp-includes/ Resources
  • 41. Questions? Drew Jaynes | @DrewAPicture Slides: http://drewf.us/wcct