3

There are certain content types such as book pages that I don't want to appear on the search results page. I found example code implementing this on drupal 7 here

/**
 * Implements hook_query_alter().
 * removes content types defined in the excluded_content_types array from search results
 */
function hook_query_alter(&$query) {
  $is_search = FALSE;
  $excluded_content_types = array(
      'product',
      'billboard',
    );
  foreach ($query->getTables() as $table) {
    if ($table['table'] == 'search_index') {
      $is_search = TRUE;
    }
  }
  if ($is_search) {
    foreach ($excluded_content_types as $content_type) {
      $query->condition('n.type', $content_type, '<>');
    }
  }
}

However I want to implement this in 8. Is there a way to exclude certain content types from search results?

UPDATE: I've also attempted to restrict the search types from within the search-result.html.twig however it does not seem like I have the content type variable available.

{{ attach_library('classy/search-results') }}
{{ title_prefix }}

{{ dump(info_split) }}

<h3{{ title_attributes.addClass('search-result__title') }}>
  <a href="{{ url }}">{{ title }}</a>
</h3>
{{ title_suffix }}
<div class="search-result__snippet-info">
  {% if snippet %}
    <p{{ content_attributes.addClass('search-result__snippet') }}>{{ snippet }}</p>
  {% endif %}
  {% if info %}
    <p class="search-result__info">{{ info }}</p>
  {% endif %}
</div>

When performing {{ dump(info_split) }} it does not show content type as an available variable.

3 Answers 3

3

Configuring search is easy with Search API. Excluding node types from indexing is one of its basic config options.

https://www.drupal.org/project/search_api

When you set up your index and go to the configuration page, you can exclude bundles (types).

1
  • I'd rather intercept it and remove it in a hook or template instead. I'd like to avoid installing new modules, especially since I only plan on removing one content type, and there would be less than 10 nodes. Is that a possibility?
    – Amy
    Commented Sep 23, 2016 at 18:28
1

I had a similar issue and i managed it by writing

YOUR_THEME_NAME_preprocess_search_result(&$variables)

and by enabling advanced search for anonymous users. Also hide the options from users in

YOUR_THEME_NAME_form_search_form_alter(&$form, FormStateInterface $form_state, $form_id)

use these functions and kint($variables) and kint($form). Hope it will help

2
  • Where should I write these codes???
    – Sky
    Commented Apr 16, 2018 at 18:02
  • In your YOUR_THEME_NAME.theme file Commented Apr 17, 2018 at 4:51
0

We created a new search plugin to restrict indexing of specific CTs.

/**
 * Override standard core node search to exclude specific bundles from indexing.
 */
function mymodule_search_plugin_alter(array &$definitions): void {
  if (isset($definitions['node_search'])) {
    $definitions['node_search']['class'] = MyModuleNodeSearch::class;
  }
}

And just override updateIndex and indexStatus methods:

<?php

namespace Drupal\mymodule\Plugin\Search;

use Drupal\node\Plugin\Search\NodeSearch;

/**
 * Extend core node search to exclude specific content types from search.
 */
class MyModuleNodeSearch extends NodeSearch {

  const EXCLUDED_BUNDLES = ['article', 'basic_page'];

  public function updateIndex() {
    // ...
    // parent stuff.
    $query->condition('n.type', self::EXCLUDED_BUNDLES, 'NOT IN');
    // ... other query stuff.
  }
  
  public function indexStatus() {
    $total = $this->database->query('SELECT COUNT(*) FROM {node} [n] WHERE [n].[type] NOT IN ( :bundles[] )', [':bundles[]' => self::EXCLUDED_BUNDLES)->fetchField();
    $remaining = $this->database->query("SELECT COUNT(DISTINCT [n].[nid]) FROM {node} [n] LEFT JOIN {search_dataset} [sd] ON [sd].[sid] = [n].[nid] AND [sd].[type] = :type WHERE ([sd].[sid] IS NULL OR [sd].[reindex] <> 0) AND [n].[type] NOT IN ( :bundles[] )", [
      ':type' => $this->getPluginId(),
      ':bundles[]' => self::EXCLUDED_BUNDLES,
    ])->fetchField();

    return ['remaining' => $remaining, 'total' => $total];
  }
}

Nowadays there are lots of modules that allows you restrict indexing/showing specific CTs. Here is a module uses same approach as we: https://dgo.to/search_exclude

BTW: just in case if you need programmatically reindex core search via drush then use this solution

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.