Today i will show how you can use your custom WordPress query by simply using the hook pre_get_posts. This is an interesting hook that can modify the query before execution. As a result you can alter the WordPress query results aka the posts that come up to your blog.
There are several options to do this. Whether you want to limit the number of posts shown per page for example, or to include/exclude specific categories. You can also exclude or even order sticky posts chronologically.
All these gave me some interesting ideas on how to modify the WordPress query and experiment with the homepage. Currently it shows the latest posts, but with a few lines of code it can show one or two posts from each category. This alongside with some custom css can give you a magazine style homepage. I’m planning to write this snippet in an upcoming post.
Of course there is an extended reference with examples on how to use the hook, in the Codex. So it’s time to take a look in some examples.
Show Posts From Specific Categories
function exclude_categories( $query ) { if ( $query->is_home() && $query->is_main_query() ) { $query->set( 'cat', '-1,-1347' ); } } add_action( 'pre_get_posts', 'exclude_category' );
In this example we modify the WordPress query in order to show us posts from all the categories except the categories with ID 1 and 1347. If we remove the ‘-‘ symbol the query will show posts only from categories with ID 1 and 1347, It’s the opposite.
Pretty straight forward, so let go on to the next example.
Exclude Sticky Posts, Order Sticky Posts Chronologically
/* * Exclude categories from homepage */ function gt_exclude_sticky( $query ) { if ( $query->is_home() && $query->is_main_query() && !is_admin() ) { //show the sticky post in its chronological place $query->set( 'ignore_sticky_posts', 1 ); //exclude the sticky post completely $query->set( 'post__not_in', get_option( 'sticky_posts' ) ); } } add_action( 'pre_get_posts', 'gt_exclude_sticky' );
WordPress Query- My Custom Search Plugin
Another example is to modify the search query and filter the results. The idea is to modify the results so that when a visitor clicks a category and searches for something, the search is done only to the respective category. On the other hand, if the visitor searches for something when in homepage or any other page, the search includes the whole site.
Let’s see the snippet and explain it further on.
/* * Modify search results. * Search only in the visited category, or search the whole site. */ function gt_filter_search_results( $query ) { $wp_session = WP_Session::get_instance(); if ( is_category() && ! is_admin() ) { $wp_session['temp_cat_id'] = get_query_var( 'cat' ); } if( isset( $wp_session['temp_cat_id'] ) ) { $cur_category = $wp_session['temp_cat_id']; } else { $cur_category = 0; } if ( ! is_admin() && $query->is_main_query() ) { if ( $query->is_search ) { $query->set( 'cat', $cur_category ); unset( $wp_session['temp_cat_id'] ); } } } add_action( 'pre_get_posts', 'gt_filter_search_results' ); add_filter( 'wp_session_expiration', function() { return 1*60; } ); // Set expiration to 60 seconds
The concept is easy enough. When a visitor clicks one of the categories, the category id is stored in a session variable. When the visitor is searching something, the WordPress query has results only from this category id. Otherwise, the result contains posts and pages of the default WordPress query aka the whole site.
The Session can be handled either by the default PHP Session, or by the plugin WP Session Manager. After installing the plugin we add a new session instance.
$wp_session = WP_Session::get_instance();
We can store and retrieve variables the usual way. The only drawback of the plugin is that the expiration doesn’t work atm. Either it’s a problem with the plugin or just a compatibility issue with the current version of WordPress. Whatever the case, it’s a known issue.
The Story Goes On
There is a lot of work to be done, in order to consider this a plugin. It needs testing, some extra features and perhaps it’s own dedicated widget. So the story has just begun.
[…] have previously written a post on how to auto-manipulate sticky posts here. There you could make sticky posts disappear from the home page, or you could put the sticky post […]