Skip to content

Instantly share code, notes, and snippets.

@PrafullaKumarSahu
Created October 13, 2015 09:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PrafullaKumarSahu/0e2ef6b1c67a0bf4ae55 to your computer and use it in GitHub Desktop.
Save PrafullaKumarSahu/0e2ef6b1c67a0bf4ae55 to your computer and use it in GitHub Desktop.
Introducing pre_get_posts :-
------------------------------
class WP_Query{
function &get_posts(){
$this->parse_query();
//pre_get_posts()
do_action_ref_array( 'pre_get_posts', array( &$this ) );
}
}
This is used something like this
function nacin_alter_home( $query ){
if( $query->is_home() ){
$query->set( 'author', '-5' );
}
}
add_action( 'pre_get_posts', 'nacin_alter_home' );
'pre_get_posts' fires for every post query:-
--> get_posts()
--> new WP_Query()
--> That random recent posts widget your client installed without you knowing
--> Everything
so, What Can be done if we want it just on the main query
function nacin_alter_home( $query ){
global $wp_the_query;
if ( $wp_the_query === $query && $query->is_home() ){
$query->set( 'author', '-5' );
}
}
add_action( 'pre_get_posts', 'nacin_alter_home' );
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 we use query_posts()
query_posts( 'author=-5' );
while( have_posts() ):
the_post();
endwhile;
wp_reset_query();
What query_posts( 'author=-5' ); does ?
function query_posts( $query ){
//break the reference to $wp_the_query
unset( $wp_query );
$wp_query = &new WP_Query( $query );
return $wp_query;
}
What wp_reset_query() does
function wp_reset_query(){
//Restore reference to $wp_the_query
unset( $wp_query );
$wp_query = &$wp_the_query;
//Reset the goals, too
wp_reset_postdata();
}
Calling the_post() ?
wp_reset_query() will reset $wp_query and the globals.
Calling $my_query->the_post() ?
wp_reset_postdata() will reset the globals
in wordpress 3.3
Rather than:
$wp_the_query === $other_query_object
we can call:
$other_query_object->is_main_query()
is_main_query(), the function, will act on $wp_query, like any other conditional tag
On Page Template
query_posts( $query_string . '&author=-5&posts_per_page=25' );
get_header();
while( have_posts() ):
the_post();
endwhile;
function nacin_my_template( $query ){
if ( !$query->is_main_query() )
return;
$query->set( 'author', '-5' );
$query->set( 'posts_per_page', '25' );
}
add_action( 'pre_get_posts', 'nacin_my_template' );
Five most recent posts by author with ID 15 in the toast
<?php
$foo = new WP_Query( array( 'posts_per_page' => 5, 'author' => 15, 'category_name' => 'toast' ) )
?>
using tax_query :-
<?php
$foo = new WP_Query( array( 'post_per_page' => 5, 'author' => 15, 'tax_query' => array( array( 'taxonomy' => 'category', 'field' => 'slug', 'terms' => 'toast' ) ) ) );
?>
Querying two categories:-
<?php
$foo = new WP_Query( array( 'post_per_page' => 5, 'author' => 15, 'tax_query' => array( array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array( 'toast', 'breakfast' ),
'operator' => 'AND'
) ) ) )
?>
Querying a category and a tag:-
<?php
$foo = new WP_Query( 'posts_per_page' => 5, 'author' => 15, 'tax_query' => (
'relation' => 'AND',
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'toast',
),
array(
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => 'wheat'
)
) )
?>
Querying a category and a tag, excluding subcategories:
<?php
$foo = new WP_Query( array(
'posts_per_page' => 5,
'author' => 15,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'toast',
'include_childdren' => false
),
array(
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => 'wheat'
)
)
) )
?>
Using the meta_query:--
->Five posts with feature images
<?php
$foo = new WP_Query( array( 'posts_per_page' => 5, 'meta_query' => array( array( 'key' => '_thumbnail_id' ) ) ) );
?>
->Five posts using the same thumbnail ID 100
<?php
'posts_per_page' => 5,
'meta_query' => array( array( 'key' => '_thumbnail_id', 'value' => 100, 'type' => 'NUMERIC' ) )
?>
Using the meta query : multiple queries
->Five posts with featured images AND flagged as 'featured' post
<?php
$foo = new WP_Query( array( 'posts_per_page' => 5, 'meta_query' => array( array( 'key' => '_thumbnail_id' ), array( 'key' => '_featured' ) ) ) );
?>
->Five posts with featured images OR flagged as 'featured' posts
<?php
$foo = new WP_Query( array( 'posts_per_page' => 5, 'meta_query' => array( 'relation' => 'OR', array( 'key' => '_thumbnail_id' ), array( 'key' => '_featured' ) ) ) );
?>
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()
pre_get_posts is a powerful and fleexible hook Just use it properly
Always check if you are modifying the main query using $query->is_main_query()
comments:-
It's not possible to alter the loop on a template by checking (is_page_template()) inside pre_gest_posts. if you run multiple queries on the template it fails.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment