Codex tools: Log in
Contents |
This hook is called after the query variable object is created, but before the actual query is run.
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 - no return value is necessary).
<?php add_action( 'pre_get_posts', 'your_function_name' ); ?>
The $query object is passed to your function by reference. You do not need to declare globals or return a value. Any changes you make to the object from inside your function are made to the original immediately.
When using pre_get_posts, be aware of the query you are changing. One useful tool is is_main_query(), which can help you ensure that the query you are modifying is only the main query.
This filter can also be used to affect admin screen queries. Be sure to check if your modification is affecting your post edit screens. For example, just checking is_main_query() and is_post_type_archive('custom') will change your query for the edit.php?post_type=custom screen, unless you also check for !is_admin()
pre_get_posts runs before WP_Query has been setup. Some template tags and conditional functions that rely on WP_Query will not work. For example, is_front_page() will not work, although is_home()will work. In such cases, you will need to work directly with the query vars, which are passed to the pre_get_posts hook as an argument ($query in examples on this page).
Using the offset argument in any WordPress query can break pagination. If you need to use offset and preserve pagination, please keep in mind that you will need to handle pagination manually. Read the codex article Making Custom Queries using Offset and Pagination for more information.
This is how you can exclude categories of posts from displaying in your blog. For example, if you have 2 categories of posts (uncategorized '1' and another '1347') that you don't want to display on your 'home' blog page, you can use the following in your plugin to omit these categories:
function exclude_category( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
$query->set( 'cat', '-1,-1347' );
}
}
add_action( 'pre_get_posts', 'exclude_category' );
Often when readers of your blog search for something, it is most likely to be in posts rather than pages. So, you might like to exclude pages in your search results. It is possible to create an action hook that limits the search results by showing only results from pages.
The following example demonstrates how to do that:
function SearchFilter($query) {
if ($query->is_search) {
$query->set('post_type', 'post');
}
return $query;
}
add_action('pre_get_posts','SearchFilter');
WordPress includes a single global setting for controlling the number of posts that appear on one loop page (under "Blog pages show at most" in the admin"). It is possible to create an action hook that changes / overrides the posts_per_page setting on a case-by-case basis. Best of all, this is done before the query is even executed (so there is no performance cost)!
The following example demonstrates how to override the page size ('posts_per_page') for archives of specific post types:
function hwl_home_pagesize( $query ) {
if ( is_admin() || ! $query->is_main_query() )
return;
if ( is_home() ) {
// Display only 1 post for the original blog archive
$query->set( 'posts_per_page', 1 );
return;
}
if ( is_post_type_archive( 'movie' ) ) {
// Display 50 posts for a custom post type called 'movie'
$query->set( 'posts_per_page', 50 );
return;
}
}
add_action( 'pre_get_posts', 'hwl_home_pagesize', 1 );
For reference, this is one possible example of the WP_Query object ($query) exposed by this hook. For more detail, you can also review the WP_Query codex page.
WP_Query Object
(
[query_vars] => Array
(
[page] =>
[pagename] => blog
[error] =>
[m] => 0
[p] => 0
[post_parent] =>
[post_type] =>
[subpost] =>
[subpost_id] =>
[attachment] =>
[attachment_id] => 0
[name] =>
[static] =>
[page_id] => 0
[second] =>
[minute] =>
[hour] =>
[day] => 0
[monthnum] => 0
[year] => 0
[w] => 0
[category_name] =>
[tag] =>
[cat] =>
[tag_id] =>
[author_name] =>
[feed] =>
[tb] =>
[paged] => 0
[comments_popup] =>
[meta_key] =>
[meta_value] =>
[preview] =>
[s] =>
[sentence] =>
[fields] =>
[category__in] => Array
(
)
[category__not_in] => Array
(
)
[category__and] => Array
(
)
[post__in] => Array
(
)
[post__not_in] => Array
(
)
[tag__in] => Array
(
)
[tag__not_in] => Array
(
)
[tag__and] => Array
(
)
[tag_slug__in] => Array
(
)
[tag_slug__and] => Array
(
)
)
[tax_query] =>
[meta_query] =>
[post_count] => 0
[current_post] => -1
[in_the_loop] =>
[comment_count] => 0
[current_comment] => -1
[found_posts] => 0
[max_num_pages] => 0
[max_num_comment_pages] => 0
[is_single] =>
[is_preview] =>
[is_page] =>
[is_archive] =>
[is_date] =>
[is_year] =>
[is_month] =>
[is_day] =>
[is_time] =>
[is_author] =>
[is_category] =>
[is_tag] =>
[is_tax] =>
[is_search] =>
[is_feed] =>
[is_comment_feed] =>
[is_trackback] =>
[is_home] => 1
[is_404] =>
[is_comments_popup] =>
[is_paged] =>
[is_admin] =>
[is_attachment] =>
[is_singular] =>
[is_robots] =>
[is_posts_page] => 1
[is_post_type_archive] =>
[query_vars_hash] => 41032f87127fba65fb6743b1e97d8662
[query_vars_changed] =>
[thumbnails_cached] =>
[query] => Array
(
[page] =>
[pagename] => blog
)
[queried_object] => stdClass Object
(
[ID] => 16
[post_author] => 1
[post_date] => 2012-01-31 17:23:57
[post_date_gmt] => 2012-01-31 17:23:57
[post_content] =>
[post_title] => Blog
[post_excerpt] =>
[post_status] => publish
[comment_status] => open
[ping_status] => open
[post_password] =>
[post_name] => blog
[to_ping] =>
[pinged] =>
[post_modified] => 2012-01-31 17:23:57
[post_modified_gmt] => 2012-01-31 17:23:57
[post_content_filtered] =>
[post_parent] => 0
[guid] =>