5

I have a site with 4 languages and am using the builtin search to look for content on the site. How is it possible to restrict the search results only to the currently selected language?

I tried looking into Configuration > Search Pages, but do not see any way how to do that there.

2
  • Are you using solr search or normal search with some view ? Commented Sep 6, 2016 at 7:42
  • I don't use a view for this. I am using the out-of-the-box search that you get on a fresh install of D8. The only way I found to modify the behavior of the search is either through Configuration > Search Pages or via twig templates.
    – Ondrej
    Commented Sep 6, 2016 at 8:34

4 Answers 4

7

The "Advanced" core search has this built in. If you prefer to do this from a theme - you could do it with form_alter. This basically hides the advanced search settings and sets current language as the only language to get results from, in the search block and search page.

Alternately you can just allow users to control which language they want to get results from and simply allow them to use advanced search.

Code for theme:

/**
 * Implements hook_form_FORM_ID_alter().
 */
function hook_form_search_form_alter(&$form, &$form_state) {
  $form['help_link']['#access'] = FALSE;
  $form['advanced']['#access'] = FALSE;
  $form['basic']['keys']['#title'] = '';
  $manager = \Drupal::languageManager();
  $form['advanced']['lang-fieldset']['language']['#default_value'] = [$manager->getCurrentLanguage()->getId()];
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function hook_form_search_block_form_alter(&$form, &$form_state) {
  $manager = \Drupal::languageManager();

  $form['advanced-form'] = [
    '#type' => 'hidden',
    '#value' => 1,
  ];
  $form['f[0]'] = [
    '#type' => 'hidden',
    '#value' => 'language:' . $manager->getCurrentLanguage()->getId(),
  ];
}
7
  • Sounds good. I tried adding the code above to mytheme.theme, cleared the cache and rebuilt, but there's no change. Anything else I might have to do?
    – Ondrej
    Commented Sep 7, 2016 at 13:32
  • 1
    @Ondrej Replace hook with theme name in functions
    – googletorp
    Commented Sep 9, 2016 at 6:46
  • @googletorp thx for the suggestion, but changing "hook" with theme-name didn't work. it should be put in mytheme.theme, no?
    – jimi
    Commented Apr 8, 2017 at 13:46
  • @jimi I think you may be misunderstanding. You rename the functions in the above code. So instead of "hook_form_search_form_alter" it would be "somecustomthemename_form_search_form_alter" this worked for me. I used this code and it works fine for me. Thanks googletorp.
    – SuperTony
    Commented Aug 16, 2017 at 21:16
  • This actually works for the search block form! Thanks! Is there anywhere with documentation about adding advanced filters this way? I can't find ANYTHING.
    – ProGrammar
    Commented Oct 27, 2017 at 19:45
7

You can use simple way hook_query_TAG_alter. Example return node for current language.

<?php

use Drupal\Core\Database\Query\AlterableInterface;

/**
 * Implements hook_query_TAG_alter(): tag search_$type with $type node_search.
 */
function MYMODULE_query_search_node_search_alter(AlterableInterface $query) {
  $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
  $query->condition('n.langcode', $language, '=');
}
2
  • Right, so there's really no inbuilt way to do this - at least I know that for sure now :) I'm not a module developer, so, can this be somehow done on the theme level (like in mytheme.theme maybe)?
    – Ondrej
    Commented Sep 6, 2016 at 12:19
  • Same question here, is this also possible on theme level?
    – 0711master
    Commented Jan 6, 2019 at 11:46
0

There's a community contributed module that aims to solve this issue: Search by current language.

There's no configuration needed, it just a matter of installing and enabling the module and use Drupal's core search.

-1
/**
 * Implements hook_query_TAG_alter()
 */    
function hook_query_search_node_search_alter(&$query) {
      $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
      $query->condition('i.langcode', [$language, 'und', 'zxx'], 'IN');
}
3
  • 2
    Thanks for providing an answer. Instead of only providing code, I encourage you to extend the answer with an explanation/give more context (what is the difference with other answers).
    – Watergate
    Commented Apr 23, 2020 at 9:26
  • There already is a similar answer, what exactly makes your answer different?
    – leymannx
    Commented Apr 23, 2020 at 17:56
  • @leymannx The main difference seems to be that this code snippet includes results that have undefined language where as the code snippet from MrD is looking for results in the same language only).
    – Mike
    Commented Feb 28 at 15:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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