Deprecated: Relevanssi has long supported searching without a search term. These instructions are not necessary.
Version 1.7.3 introduces the possibility to use Relevanssi without a search term. This is useful when you have extra query arguments that can be used to narrow the search, but which would be useful without a search term present.
This was originally implemented for a restaurant search, where the users can search for restaurants based on search terms, opening hours and price category. The client wished to be able to use the opening hours and price category with and without a search term.
The problem is, Relevanssi doesn’t trigger without a search term. To fix that, you need to use a new filter hook relevanssi_search_ok
. Add this code to your site:
add_filter( 'relevanssi_search_ok', 'search_trigger' ); function search_trigger( $search_ok ) { global $wp_query; if ( ! empty( $wp_query->query_vars[ 'price' ] ) ) { $search_ok = true; } return $search_ok; }
This function will trigger Relevanssi, when the query var price
appears in the query.
Of course, without a search term, Relevanssi will find nothing. So, you need another function attached to relevanssi_hits_filter
.
It needs to have something like this:
add_filter( 'relevanssi_hits_filter', 'rlv_hits_filter' ); function rlv_hits_filter( $hits ) { if ( empty( $hits[0] ) ) { // no search hits, so must create new $args = array(...some arguments to fetch posts by...); $hits[0] = get_posts( $args ); } else { // posts available, take only those that match the conditions $ok = array(); foreach ( $hits[0] as $hit ) { if (...post matches conditions...) { array_push( $ok, $hit ); } } $hits[0] = $ok; } return $hits; }
Make this a proper function and hook it to relevanssi_hits_filter
and it’ll work.
Falling back to native WordPress search
Joel Stransky contributed the following:
I have what I feel is a pretty common situation. In the absence of a search term, I’m ok with missing out on Relevanssi’s benefits and just need native WP behavior (which matches on the sub queries even if no search phrase exists). In my current project I’m only modifying meta_query
and tax_query
so that’s all I check for to ensure I want to do this.
Add this code to your site:
// approve the search when there are active filters // but no search term add_filter( 'relevanssi_search_ok', 'search_trigger' ); function search_trigger( $search_ok ) { global $wp_query; if ( ! isset( $wp_query->query['s'] ) && isset( $wp_query-&>query_vars['tax_query'] ) || isset( $wp_query->query_vars['meta_query'] ) ) { $search_ok = true; } return $search_ok; }
Then in the hits filter, run a similar check, turn nopaging
on and return the results of get_posts()
with my modified query_vars
. Add this to your site:
add_filter( 'relevanssi_hits_filter', 'rlv_hits_filter' ); /** * return results when there are active filters but no search term * @param array $hits $hits[0] is a list of matched WP_Post objects * $hits[1] is the search term if any * @return array $hits */ function rlv_hits_filter( $hits ) { global $wp_query; if ( ! $hits[1] && isset( $wp_query->query_vars['tax_query'] ) || isset( $wp_query->query_vars['meta_query'] ) ) { $wp_query->set( 'nopaging', true ); $hits[0] = get_posts( $wp_query->query_vars ); } return $hits; }
I would love to try this but don’t understand what I need to do be able to search without a query string, could you please add som example code?
/Jens
The first function in the post is used to make Relevanssi active, when a certain query variable is present. This is the query variable you want to use to control what is shown if there is no search term present. So, in this case, if the query variable “price” appears in the URL, Relevanssi is activated, whether there’s search term (“s”) or not.
Then you’ll also have another function that uses the query variable to restrict the searches. This is hooked to “relevanssi_hits_filter” and in this case it would go through all the search hits and discard those that don’t match the value of the “price” query variable.
So far pretty simple, right? However, if this is all you do, you’ll end up with no results when you don’t use the search term, because there are no search results to process. You need to find something to process yourself. This is where the second code snippet comes into play. This code goes to the function hooked to “relevanssi_hits_filter”. It checks the $hits[0] array. If it’s empty, there are no posts to process, so we need to get some. The easiest solution is to use get_posts to fetch every post in the database and then process like you would with search results.
However, that’s perhaps a bit ineffecient, as the get_posts() is a fairly powerful function in itself and you can probably use it to limit the posts.
So, these two snippets of code are all you need. The first is a full function in itself, the second needs to go to a function that is then hooked to “relevanssi_hits_filter”.
So, if I understand this correctly, if we have a variable named “price” in the URL, we could use a meta-search like so:
$query = new WP_Query( array( ‘meta_key’ => ‘price’, ‘meta_value’ => $searchvalue ) );
$hits[0]=$query->posts
where $searchvalue is the value of the price-parameter in the URL, and use that in the second function above (the one attached to the relevanssi_hits_filter). Would that work?
Yes, that’s how you can do it.
hello, using relevanssi and works fine. i’m not an expert in coding and need to know what code/function to put and where to make relevanssi work without any term inside. please help
I’m sorry, but it’s a complicated thing and requires programming knowledge. If you don’t understand the instructions in this post, it’s too complicated to explain in a comment here. You also need to have a Premium license.
Hi Mikko,
Great plugin! I just have a small question how do I turn off the search without term in the latest version. I wan’t to show a “No results were found, you must enter a keyword” when the user doesn’t type anything. I don’t want to display a list of everything in my site.
Thanks!
Looks like there’s a small bug somewhere. It’s not supposed to work like that. I’ll fix it for the next version.
Actually, looking at this, a search without a search term passes right through Relevanssi without Relevanssi being activated. Relevanssi doesn’t touch the posts WordPress finds. So, this is actually the WordPress default behaviour and has nothing to do with Relevanssi.
You can probably fix that on your search results template though, just check what’s in the query and display whatever you want instead of the posts if the query is empty.
Hi,
I just found your plugin in google and I wondered if it could be adapted to what I need. Right now I’m working on a project for a friend’s car shop. Using Types and Views I set up front-end filters to search cars by brand, model or year, or a combination thereof. These parameters are set in every car using select box custom fields. I chose select boxes so I could previously set those values instead of letting the client fill them in. The front-end filters work but they don’t auto populate according to a user’s selection. Say, a wants to filter car by Ford brand. I expect the other 2 controls would update (via ajax) to only show car models and years that are set to that brand.
Could your plugin be customized to this behavior with or without the View plugin’s filters I’m currently using?
thanks
Roberto
Sorry but no, Relevanssi doesn’t do that, Relevanssi is just an “under-the-hood” search engine.
how’d you go with that search Roberto? i have just purchased Views with the same intention… but I dont actually know how to do it…..
Hi, I had to hire a php developer to build some custom code that interacts with the search fields.
I think the developers of View could build this functionality into their code but it’s not in their list of priorities.
Is there a way to use this filter to turn off relevanssi? I have a custom post type, where the user can perform a search on the archive page. Doing the below returns 0 results.
add_action( ‘relevanssi_search_ok’, ‘mcfta_turn_off_relevanssi’ );
function mcfta_turn_off_relevanssi($search_ok) {
if (is_post_type_archive( ‘event’ )) {
$search_ok = false;
}
return $search_ok;
}
That’s a start, but you’ll also have to turn off relevanssi_prevent_default_request(), so that Relevanssi doesn’t kill off the default search.
Do I still need Premium to use this function to search without a search term?
No, I don’t think this has actually ever been a Premium exclusive feature.
K great, thanks for the quick response. I just asked because the nav menu has “Buy Premium” highlighted green as current category.
That’s not a current category highlight, that’s a “please notice me and buy buy buy” highlight. =)
Thank you for the wonderful plug-in.
Since there is a place which usage does not understand, please let me ask a question.
Now, it is multisite and is using Relevanssi.
relevanssi_hits_filter is specified so that it can search, even if two or more custom taxonomy to searchterm cannot be found, but searchblogs cannot make it function well.
If it becomes as it is used, inputting search term, the searchblogs will operate normally.
Aren’t any hints got?
Since the translation engine is used, I think that a text is strange.
I’m sorry.
The free version of Relevanssi does not work with multisite. You need Relevanssi Premium for that.
Thank you for the instant reply.
I am allowed to purchase to the beginning of this year, and am using the present premium version.
Ok. You should note that relevanssi_hits_filter is not available in multisite searches (when search_blogs is used). You can’t use taxonomy filtering, either. Multisite searching only supports post type filtering.
Thank you for your reply. I am sorry for the delay in it and the replying here.
An understanding was completed for a while, seeing the function of Relevanssi, since Mikko taught. Moreover, if it may not understand in the middle of work, please let me ask a question.
Thank you.
I’ve just had to do this for a client. I blogged about it here: http://keithdevon.com/allowing-null-search-relevanssi/
Need your Help. I am using a Custom Post Type “Listing” and I have a Taxonomy “Location”. In the Taxonomy “Location” I have multiple Categories for different locations. How do I search only “Richmond” Category posts when the Input Search form is Empty? I am trying to use the above example, but I’m not having any luck in getting this to work. Much help is appreciated.
In the bottom example, replace this line:
$args = array(…some arguments to fetch posts by…);
with arguments that fetch posts in the “Richmond” category. See WordPress Codex documentation on get_posts() to see how that is done.
I did do that but it didn’t work. On the Top part, where it says “Price”, What do I replace that with.
What does the URL look like when you do a search? You need to pick a parameter that appears in the search URL. Might be “location”?
Do I put all this code (above) in the themes Function.php file?
Sorry for all the questions.
Shawn
Yes, theme functions.php is a good place.
Yeah, this is not working. I just get nohting. I have no clue
Show me:
1) What does the URL look like when you do a search?
2) The code you currently have (put it in a Pastebin and link it here)
Hi Mikko, Again… Thanks for all the help. Here is a complete of what I am doing:
url from search result: .com/listing/?s=
What I have in my Functions.php file:
add_filter(‘relevanssi_search_ok’, ‘search_trigger’);
function search_trigger($search_ok) {
global $wp_query;
if (!empty($wp_query->query_vars[‘richmond’])) {
$search_ok = true;
}
return $search_ok;
}
// Second Part
if ($hits[0] == null) {
// no search hits, so must create new
$args = array(‘post_type’ => ‘listing’,’location’ => ‘richmond’, ‘posts_per_page’=>3);
$hits[0] = get_posts($args);
}
else {
// posts available, take only those that match the conditions
$ok = array();
foreach ($hits[0] as $hit) {
if ($args)
array_push($ok, $hit);
}
$hits[0] = $ok;
}
What my Search Form Looks Like:
My Post Type is: Listing
My Taxonomy is: Location
My Category in Location is: Richmond
Relevance is Indexing only: Listing (Post Type) and Location (Taxonomy)
In the first function, “richmond” should be “location”. The second part is missing the actual function. I’ve changed the example a bit so that it includes the complete function, so it’s easier to understand.
Hi Mikko!
I’m wondering if relevanssi_search_ok is mandatory. Because relevanssi_hits_filter is triggered for my search anyway and there’s no difference in search results (and in SQL queries too) when I remove relevanssi_search_ok.
If there’s no need for it, then drop it. It’s only necessary when there’s no search term ($wp_query->query_vars[“s”]), because in those cases the search isn’t triggered at all.
I’ve just tested it once more and now I understand. relevanssi_search_ok is necessary when ‘s’ param is not present at all. I have it but it’s empty and search is triggered.
I combined both functions and used for empty string searches.
Thank you.
Hello Mikko,
is it possible to this with custom wp_query? and if yes.. how?
Thanks,
Yes, you need to use relevanssi_do_query($wp_query); to run Relevanssi on the WP_Query.
I have what I feel is a pretty common situation. In the absence of a search term, I’m ok with missing out on Relevanssi’s benefits and just need native WP behavior (which matches on the sub queries even if no search phrase exists)
In my current project I’m only modifying meta_query and tax_query so that’s all I check for to ensure I want to do this.
// approve the search when there are active filters
// but no search term
add_filter('relevanssi_search_ok', 'search_trigger');
function search_trigger($search_ok) {
global $wp_query;
if ( !isset($wp_query->query['s']) && isset( $wp_query->query_vars['tax_query']) || isset( $wp_query->query_vars['meta_query']) ) {
$search_ok = true;
}
return $search_ok;
}
Then in the hits filter, run a similar check, turn ‘nopaging’ on and return the results of get_posts() with my modified query_vars
add_filter('relevanssi_hits_filter', 'rlv_hits_filter');
/**
* return results when there are active filters but no search term
* @param array $hits $hits[0] is a list of matched WP_Post objects
* $hits[1] is the search term if any
* @return array $hits
*/
function rlv_hits_filter($hits) {
global $wp_query;
if ( !$hits[1] && isset( $wp_query->query_vars['tax_query']) || isset( $wp_query->query_vars['meta_query']) ) {
$wp_query->set('nopaging', true);
$hits[0] = get_posts( $wp_query->query_vars );
}
return $hits;
}
Unless I’m overlooking something, this appears to work great.
Hi, this looks good, and I’ve added this to the post content. Thanks!