I have 3 pages I wish to exclude from search. Is there a way to exclude them from coming up in the search results? Incidentally, is it also possible for other content types other than Pages alone?
5 Answers
I haven't tried this in Drupal 7, but it doesn't seem to have changed much. There is an easy "hack" and a "better" way to do this:
The easy way is to override search-result.tpl.php. You can copy the default search-result.tpl.php file from the core search module into your theme. Then, inside the template you can use code like this to exclude results based on node ID:
if ($result["node"]->nid != <excluded nid>) {
// search result display code
}
The only drawback with this approach is that you will have certain pages of search results that have less results than others (if you show 10 results per page and you don't display 3 on one page, then you will only have 7 results). You could also do similar hiding in template_preprocess_search_result with the same drawback.
The right/"better" way to do this is to actually exclude the list of nodes from ever being indexed. To do that you'll have to implement hook_query_alter. You can check out a post describing exactly how to do this over on Phase2's blog.
As you can see in the blog entry, you can also exclude by content type.
Note that the Drupal 6 way was to use hook_db_rewrite_sql. There is a post over at Lullabot on that.
-
2This is one of the things that continues to INFURIATE me about Drupal. NOWHERE in the documentation does it tell you that you can reference the
$result
variable to get at this data.– cowgodCommented Jan 12, 2013 at 4:52
You can use Views to override search results (including all its features: filtering, sorting, etc).
Create a custom field such as "Exclude this node from search," and set the filter to exclude nodes with that field or/and certain content types.
You might also try the module Search exclude nid. It is very easy to use. I did a test and it did exactly this and not anything else.
Another option: It appears the Search configuration module (search_config 7.x-1.1-beta2 or above) also have some ability to restrict search results from showing individual items. The Search configuration module can also restrict search results by the content type. This is a role based restriction.
You can use the Search Configuration module. Once installed, just navigate to node you want to exclude, go to it's edit page, and scroll all the way down to 'Publishing options' -- you'll see an option to exclude the node from search results.
There's also the Search exclude nid module, which is more lightweight... but you'll have to manually type in each node you want to exclude.
For Drupal 7. You can hide the node from search results by using custom field. In my case, I have created a custom field in the name of Archive to the desired content type and with the help of that custom field you can write the my_module_query_alter functionality.
Code
function my_module_query_alter(QueryAlterableInterface $query) {
$is_search = $is_node_search = FALSE;
$node_alias = FALSE;
foreach ( $query->getTables() as $table ) {
if ( $table['table'] == 'search_index' || $table['table'] == 'tracker_user') {
$is_search = TRUE;
}
if ( $table['table'] == 'node' || $table['table'] == 'tracker_user') {
$node_alias = $table['alias'];
$is_node_search = TRUE;
}
}
if ( $is_search && $is_node_search ) {
$nids = [];
// Run entity field query to get nodes that are 'suppressed from public'.
$efq = new EntityFieldQuery();
$efq->entityCondition('entity_type', 'node')
->fieldCondition('field_archive', 'value', 1, '=');
$result = $efq->execute();
if ( isset($result['node']) ) {
$nids = array_keys($result['node']);
}
if ( count($nids) > 0 ) {
$query->condition(sprintf('%s.nid', $node_alias), $nids, 'NOT IN');
}
}
}