This is a presentation for the November WordPress Melbourne meetup. It shows how to modify your main WordPress query the right way, using the pre_get_posts hook, rather than using query_posts() or even WP_Query().
26. query_posts()
function &query_posts($query) {
// Destroys the Global $wp_query variable!
unset($GLOBALS['wp_query']);
$GLOBALS['wp_query'] = new WP_Query();
return $GLOBALS['wp_query']->query($query);
}
27. query_posts()
function &query_posts($query) {
unset($GLOBALS['wp_query']);
// Creates new $wp_query variable
$GLOBALS['wp_query'] = new WP_Query();
return $GLOBALS['wp_query']->query($query);
}
30. Thatâs running 2* queries!
Itâs running the query WordPress
thinks you want.
Itâs then running your new query
you actually want.
31. * In actual fact, WP_Query
doesnât just run one query.
It runs four!
So, that means your template
is actually running eight queries!
32. Donât forget to reset
// Restores the $wp_query reference to $wp_the_query
// Resets the globals
wp_reset_query();
// Resets the globals
wp_reset_postdata();
34. Say hello to pre_get_posts
[From the Codex]
The pre_get_posts action gives developers
access to the $query object by reference.
(any changes you make to $query are made
directly to the original object)
35. Say hello to pre_get_posts
What this means is we can change our
main query before itâs run
36. pre_get_posts
pre_get_posts fires for every post query:
â get_posts()
â new WP_Query()
â Sidebar widgets
â Admin screen queries
â Everything!
38. In functions.php
[example 1]
function my_pre_get_posts( $query ) {
// Check if the main query and home and not admin
if ( $query->is_main_query() && is_home() && !is_admin() ) {
// Display only posts that belong to a certain Category
$query->set( 'category_name', 'fatuity' );
// Display only 3 posts per page
$query->set( 'posts_per_page', '3' );
return;
}
}
// Add our function to the pre_get_posts hook
add_action( 'pre_get_posts', 'my_pre_get_posts' );
39. In functions.php
[example 1]
function my_pre_get_posts( $query ) {
// Check if the main query and home and not admin
if ( $query->is_main_query() && is_home() && !is_admin() ) {
// Display only posts that belong to a certain Category
$query->set( 'category_name', 'fatuity' );
// Display only 3 posts per page
$query->set( 'posts_per_page', '3' );
return;
}
}
// Add our function to the pre_get_posts hook
add_action( 'pre_get_posts', 'my_pre_get_posts' );
40. In functions.php
[example 1]
function my_pre_get_posts( $query ) {
// Check if the main query and home and not admin
if ( $query->is_main_query() && is_home() && !is_admin() ) {
// Display only posts that belong to a certain Category
$query->set( 'category_name', 'fatuity' );
// Display only 3 posts per page
$query->set( 'posts_per_page', '3' );
return;
}
}
// Add our function to the pre_get_posts hook
add_action( 'pre_get_posts', 'my_pre_get_posts' );
41. In functions.php
[example 1]
function my_pre_get_posts( $query ) {
// Check if the main query and home and not admin
if ( $query->is_main_query() && is_home() && !is_admin() ) {
// Display only posts that belong to a certain Category
$query->set( 'category_name', 'fatuity' );
// Display only 3 posts per page
$query->set( 'posts_per_page', '3' );
return;
}
}
// Add our function to the pre_get_posts hook
add_action( 'pre_get_posts', 'my_pre_get_posts' );
42. In functions.php
[example 1]
function my_pre_get_posts( $query ) {
// Check if the main query and home and not admin
if ( $query->is_main_query() && is_home() && !is_admin() ) {
// Display only posts that belong to a certain Category
$query->set( 'category_name', 'fatuity' );
// Display only 3 posts per page
$query->set( 'posts_per_page', '3' );
return;
}
}
// Add our function to the pre_get_posts hook
add_action( 'pre_get_posts', 'my_pre_get_posts' );
43. In functions.php
[example 2]
function my_pre_get_posts( $query ) {
// Check if the main query and movie CPT archive and not admin
if($query->is_main_query() && is_post_type_archive('movie') && !is_admin()){
// Display only posts from a certain taxonomies
$query->set( 'tax_query', array(
array( 'taxonomy' => 'genre',
'field' => 'slug',
'terms' => array ( 'fantasy', 'sci-fi' )
)
) );
return;
}
}
// Add our function to the pre_get_posts hook
add_action( 'pre_get_posts', 'my_pre_get_posts' );
44. In functions.php
[example 2]
function my_pre_get_posts( $query ) {
// Check if the main query and movie CPT archive and not admin
if($query->is_main_query() && is_post_type_archive('movie') && !is_admin()){
// Display only posts from a certain taxonomies
$query->set( 'tax_query', array(
array( 'taxonomy' => 'genre',
'field' => 'slug',
'terms' => array ( 'fantasy', 'sci-fi' )
)
) );
return;
}
}
// Add our function to the pre_get_posts hook
add_action( 'pre_get_posts', 'my_pre_get_posts' );
45. In functions.php
[example 2]
function my_pre_get_posts( $query ) {
// Check if the main query and movie CPT archive and not admin
if($query->is_main_query() && is_post_type_archive('movie') && !is_admin()){
// Display only posts from a certain taxonomies
$query->set( 'tax_query', array(
array( 'taxonomy' => 'genre',
'field' => 'slug',
'terms' => array ( 'fantasy', 'sci-fi' )
)
) );
return;
}
}
// Add our function to the pre_get_posts hook
add_action( 'pre_get_posts', 'my_pre_get_posts' );
46. In functions.php
[example 2]
function my_pre_get_posts( $query ) {
// Check if the main query and movie CPT archive and not admin
if($query->is_main_query() && is_post_type_archive('movie') && !is_admin()){
// Display only posts from a certain taxonomies
$query->set( 'tax_query', array(
array( 'taxonomy' => 'genre',
'field' => 'slug',
'terms' => array ( 'fantasy', 'sci-fi' )
)
) );
return;
}
}
// Add our function to the pre_get_posts hook
add_action( 'pre_get_posts', 'my_pre_get_posts' );
47. Remember...
Do:
â Use pre_get_posts
â Check if itâs the main query by using is_main_query()
â Check itâs not an admin query by using is_admin()
â Check for specific templates using is_home(), etc..
â Set up your query using same parameters as WP_Query()
Donât:
â Use query_posts()
unless you have a very good reason AND you use wp_reset_query()
( if you really need a secondary query, use new WP_Query() )
48. References
// You Donât Know Query - Andrew Nacin
http://wordpress.tv/2012/06/15/andrew-nacin-wp_query
http://www.slideshare.net/andrewnacin/you-dont-know-query-wordcamp-portland-2011
// Make sense of WP Query functions
http://bit.ly/wpsequery
// Querying Posts Without query_posts
http://developer.wordpress.com/2012/05/14/querying-posts-without-query_posts
// pre_get_posts on the WordPress Codex
http://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts
// Example code on Github
https://github.com/maddisondesigns/wpmelb-nov