How can I change the default Apache Solr URL path from "search/apachesolr_search/term" to something else?
8 Answers
The way I've typically done this is to implement hook_menu_alter(). You can then customize the url in the exact way you choose:
/**
* Implements hook_menu_alter().
*/
function example_menu_alter(&$menu) {
// Ensure Apache Solr is the default and that the menu item exists.
if (variable_get('apachesolr_search_make_default', 0) && isset($menu['search/apachesolr/%menu_tail'])) {
$menu['search/%menu_tail'] = $menu['search/apachesolr/%menu_tail'];
unset($menu['search/apachesolr/%menu_tail']);
}
}
It is non-trivial to change the search path if you are only using the apachesolr search module. Since it depends on the core search module, the path is nearly hard-coded. It depends on search/{module}/%menu_tail. If you look at search_view(), the callback for the search module, you'll find that it calls search_get_keys(), which expects the search keys to be in a particular part of the path. The apachesolr search module also uses this function to get keys, so implementing a simple hook_menu_alter() won't work on its own.
As mentioned in another answer here, if you are able to run Views 3.x, then your best bet is to use the apachesolr views module. With this module, you can easily define any number of custom paths for search results.
If you can't run 3.x, then you'll need to use a combination of form alter (specifically, search_form) and custom menu callbacks to successfully change the default search path.
This should work if you place it in settings.php:
function custom_url_rewrite_outbound(&$path, &$options, $original_path) {
// Filter to get only the apache solr links with filters so it doesn't launch it for every link of our website
if ($path == 'search/apachesolr_search/' && strpos($options['query'], 'filters') !== FALSE) {
$new_path = $path.'?'.urldecode($options['query']);
// See if we have a url_alias for our new path
$sql = 'SELECT dst FROM {url_alias} WHERE src="%s"';
$row = db_result(db_query($sql, $new_path));
// If there is a dst url_alia, we change the path to it and erase the query
if ($row) {
$path = $row;
$options['query'] = '';
}
}
}
function custom_url_rewrite_inbound(&$result, $path, $path_language) {
// See if we have a url_alias for our new path
$sql = 'SELECT src FROM {url_alias} WHERE dst="%s"';
$row = db_result(db_query($sql, $path));
if ($row) {
// We found a source path
$parts = preg_split('/[\?\&]/', $row);
if (count($parts) > 1) {
$result = array_shift($parts);
// That's important because on my website, it doesn't work with the / at the end of result
if ($result[strlen($result) - 1] == '/') {
$result = substr($result, 0, strlen($result) - 1);
}
// Create the $_GET with the filter
foreach ($parts as $part) {
list($key, $value) = explode('=', $part);
$_GET[$key] = $value;
// Add this because the pager use the $_REQUEST variable to be set
$_REQUEST[$key] = $value;
}
}
}
}
And then when you create a menu entry, you put the link to apache solr : search/apachesolr_search/?filters=tid:13
And create a url alias for search/apachesolr_search/?filters=tid:13 like products/tv.html
-
I have a feeling this is for D6. Is it easily adapted for D7, as the question asked?– pushkaCommented Aug 11, 2011 at 13:34
You could use solr views for your site search.
- Create a solr view.
- Add a page display with the path you want
- Add search text as a filter.
- Exposed form in block
- Put the block where you want your search box to go.
Check out Adding custom search paths with hook_menu by the guys at Evolving Web. It talks about how they wrote a custom module to create friendly URLs for their Solr searches. You'll probably need to tweak it a bit, but it's a good starting point.
What about creating a new menu callback like the following to make apachesolr return results at that path?
$menu['search']['page callback'] = 'apachesolr_search_view';
If you just want to change search/apachesolr_search/ to something else, for example 'inventory', you can try Global redirect module.
The trick is to create 2 aliases - one for search/apachesolr_search/ (for faceted items) and another one without trailing slash (for the main search page). Global redirect might refuse to create 2 aliases for the same destination, but you can insert it into the db directly.