3

SITUATION:

  • A View page displays all "items" that have a certain "code".

  • The code is passed via a contextual filter, e.g. /items/17, where 17 is the code.

  • A user might try to guess a code by typing it in, e.g. /items/345.

  • When the View is empty (i.e. the code is bogus), a not-found exception is raised as follows:

    function mymodule_views_pre_render(\Drupal\views\ViewExecutable $view) {
      if ($view->current_display == 'page_machine_name' && empty($view->result)) {
        throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();
      }
    }
    
  • There is a menu included as a block that's displayed at the top of the View page.

  • The menu block configuration restricts the block to pages with paths /items/*.

PROBLEM:

The menu also appears on the 404 page, since that page retains the bogus path /items/345. How can I exclude the menu block from the 404 page?

NOTES:

  • I want to display the default 404 page rather than the view with a "not found" message as its body.
  • I don't want to display the view as a block instead of as a page unless it's the only way. I already know how to solve the problem if I have to do that.
  • If there were a way to say, "Include this block only on View pages" (like you can for content types), that would be ideal.
  • There are actually three blocks that need to be excluded from the 404 page; I mention only one to make it simpler. The other blocks are a text block and a banner block.
  • I see that a solution to this problem has been proposed for Drupal 9, but not available yet.

2 Answers 2

5

Yes, the solution is not available yet in core, see https://www.drupal.org/node/2245767.

But you can use this contrib module https://www.drupal.org/project/block_in_page_not_found and negate the condition to not show the block on a 404 page:

Screenshot

1
  • This works perfectly! I wondered how I missed this in the posts I read, but redoing the search I found that my search terms just didn't include it. I hope this post will be easier to find for others who need the same direction. Nov 17, 2020 at 18:48
0

programmatically:

 $route_name = \Drupal::request()->attributes->get('_route');
  if ('system.404' === $route_name) {
    $region_name = 'content';
    $block_names = ['oneBlockID', 'andAnother'];
    foreach ($block_names as $block_name)
    if (isset($variables['page'][$region_name][$block_name])) {
      $variables['page'][$region_name][$block_name]['#access'] = FALSE;
    }
  }

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.