1

I am trying to change the way "Search results" header is rendered in D8. Unfortunately HTML is hardcoded in SearchController and not themeable. I figured I could use hook_block_view_alter to change the $build['search_results_title'], but the hook implementation from my theme never gets called:

function labweb_block_view_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  if (isset($build['search_results_title'])) {
    unset($build['search_results_title']);
  }
  kpr($build);
}

Any ideas? It seems that this hook never gets called...

  • I think the issue might be that themes do not support all hooks that are available to modules and this might be one of those. – user21641 Feb 13 '16 at 17:42
2

...but the hook implementation from my theme never gets called:

hook_block_view_alter() will not be called for themes; it is invoked only for modules. This is why your hook is never invoked.

To implement this hook, you need to create a custom module. If you need help to create a module you can check here to start.

I strongly suggest to read block_view_alter docs too.

Look at Theme Hooks to see what you can 'hook' in your theme.
For more information about hooks look here.

| improve this answer | |
0

Since you are trying to change the output returned from a page controller, you are implementing the wrong hook. The output of a page controller doesn't normally go in a block, but in a page. The only block the Search module implement is the SearchBlock class, which just outputs the form to search in a Drupal site, and redirect users to the search page. See its SearchBlock::build() method, which contains just a line of code.

return \Drupal::formBuilder()->getForm('Drupal\search\Form\SearchBlockForm');

In SearchBlockForm::buildForm(), you see the effective form build for that block.

  $route = 'search.view_' . $entity_id;
  // Notice the following line that submits the form in the search page showing the results, the one handled by the SearchController.
  $form['#action'] = $this->url($route);
  $form['#method'] = 'get';

  $form['keys'] = array(
    '#type' => 'search',
    '#title' => $this->t('Search'),
    '#title_display' => 'invisible',
    '#size' => 15,
    '#default_value' => '',
    '#attributes' => array('title' => $this->t('Enter the terms you wish to search for.')),
  );

  $form['actions'] = array('#type' => 'actions');
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => $this->t('Search'),
    // Prevent op from showing up in the query string.
    '#name' => '',
  );

To achieve what you need, you should alter the controller invoked for the search page.

As for your hook not being involved, that is because Drupal doesn't look for the implementations of that hook contained in a theme. In fact, the code invoking it is the following.

  // If an alter hook wants to modify the block contents, it can append
  // another #pre_render hook.
  $module_handler->alter(['block_view', "block_view_$base_id"], $build, $plugin);

The module handler is a service that handles modules, not themes.

Compare that code with the code used to invoke the implementations of hook_js_alter().

// Allow modules and themes to alter the JavaScript assets.
$this->moduleHandler->alter('js', $javascript, $assets);
$this->themeManager->alter('js', $javascript, $assets);

As you see, the code uses the theme manager to invoke the hook implemented by a theme.

| improve this answer | |
  • I am sure there is a question about altering a route implemented by another module. (Maybe I even asked it.) When I find it, I will add more details on how to change the controller used for the search page. – kiamlaluno Feb 14 '16 at 7:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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