23

How can I restrict the results from a default search in Drupal 7, to bring only the nodes that are in the current language?

My website has a three language switcher; the user chooses what language he wants to use when viewing the site. If he searches something, the result page bring results from other languages. Today I have only 3 enabled languages, but we plan to expand this to 6 or more.

2

You can use the global $language to know in which language you are. In Views, you can filter using "content:language -> current user language."

  • 3
    how does this help? could you replace the search page with a node? does this have any drawbacks? – jumper Jan 29 '13 at 18:57
25
+250

There's a really elegant way to do this using the apparently undocumented hook_query_node_access_alter():

function yourmodule_query_node_access_alter(QueryAlterableInterface $query) {
  $search = FALSE;
  $node = FALSE;

  // Even though we know the node alias is going to be "n", by checking for the
  // search_index table we make sure we're on the search page. Omitting this step will
  // break the default admin/content page.
  foreach ($query->getTables() as $alias => $table) {
    if ($table['table'] == 'search_index') {
      $search = $alias;
    }
    elseif ($table['table'] == 'node') {
      $node = $alias;
    }
  }

  // Make sure we're on the search page.
  if ($node && $search) {
    $db_and = db_and();
    // I guess you *could* use global $language here instead but this is safer.
    $language = i18n_language_interface();
    $lang = $language->language;

    $db_and->condition($node . '.language', $lang, '=');
    $query->condition($db_and);
  }
}

Note: this code is 100% based on the excellent Search Config module.

User's vs Content language

Some sites might have language detection configured to show the interface in the user's preferred language, while the page content is shown based on the URL or content language.

In that case, consider replacing

$language = i18n_language_interface();

with

$language = i18n_language_content();
  • Works perfect, but will it affect any query on site, like query generated from views module, or any based drupal query rather than the default "search/node/%" ? – mohamad salama Sep 24 '14 at 20:59
  • @mohamadsalama this will affect all search queries that affect node access; in other words most views queries should be affected unless you specifically disable node access checks in the advanced settings (off the top of my head & unconfirmed). – Alex Weber Sep 30 '14 at 16:21
  • This isn't an undocumented hook - it's actually the hook_query_TAG_alter() hook, where the tag is 'node_access'. My own code also checks to make sure there isn't already a language condition in the query, but otherwise is quite similar. – John Fiala Feb 23 '15 at 19:42
4

I had the same requirements, and I used the Custom search module, which includes a submodule called Custom Search Internationalization : "search content from all or current language only, and all label and selectors translation handling" (note this module provides also several other helpful features like custom search blocks). Works perfectly.

0

I don't sure search core support it.

I see the project i18nluceneapi but it doesnot support version 7 at the moment.

I'm using searchapi and create facets Language :). It can use for your case, create facets and default filter on search page.

0

You can use the Display suite module where you can choose the option View Mode->Language which gives the search results in the current language that is in the current site language.

protected by Clive Oct 12 '16 at 11:38

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.