4

I have the previous logic to feed a View in MY_TEMPLATE_preprocess_page. When the URL, where I have some paremeters passed in a user friendly way, does not exist (the parameters are not correct), I am serving a "Product not found message". However, I think it is more correct, for SEO purposes, to serve a 404-Not Found page, with the correct HTTP Headers. I am trying to achive this with drupal_not_found but the page takes a minute to load and finally shows a blank screen.

Where should I put the logic and the drupal_not_found call? Must I move it to my custom module, in MY_MODULE_init() or something? I need to access $node->nid.

Example:

Correct : http://www.example.com/products/shoes

Wrong (404) : http://www.example.com/products/dsfsdfswerweipwr

1
  • Is the view generating the page at products/%? Why do you need to know the $node->nid?
    – Kevin
    Sep 2, 2016 at 13:27

2 Answers 2

4

My personal advice is to return the "No results found" message from Views instead of issue a 404. Why? Because if you ever wind up adding products or changing the name of a product, what used to be a 404 is not anymore. I feel like from an SEO perspective you would have an uphill battle. Anyway.

One way to do this would be from a custom module. Do not do it in template.php.

/**
 * Implements hook_views_pre_render().
 */
 function mymodule_views_pre_render(&$view) {
   if ($view->name == 'myview' && some_other_conditions) {
     if (empty($view->result)) {
       drupal_add_http_header('Status', '404 Not Found');
       drupal_not_found();
       drupal_exit();
     }
  }
}

Bonus, Drupal 8:

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Drupal\views\ViewExecutable;

/**
 * Implements hook_views_pre_render().
 */
 function mymodule_views_pre_render(ViewExecutable $view) {
   if ($view->id() == 'myview' && some_other_conditions) {
     if (empty($view->result)) {
       throw new NotFoundHttpException();
     }
  }
}

Is the view generating the page at products/%? Why do you need to know the $node->nid?

0

I think the theme layer is a little bit too late to set your headers. It might break your caching.

That said, if you are sure you need your code to live in the hook_preprocess_HOOK, then you can rely on the fact that page not found is a HTTP header you can set by calling drupal_add_http_header('Status', '404 Not Found');

I would recommend instead of doing it in the preprocess hook using one of the following places

  1. if /product is a menu item you wrote yourself in a custom module, then in the callback function of your menu item do return MENU_NOT_FOUND;
  2. use hook_page_alter, you can get the node object at this hook by

    function THEMENAME_page_alter(&$page) { if ($node = menu_get_object()) { // Stuff. } }

  3. hook_init() is also a good bid, you can get the node object in the same manner as in step 2
2
  • I try to use MYMODULE_preprocess_HOOK but it does not enter there.
    – Cesar
    Sep 2, 2016 at 12:21
  • Don't use hook_init.
    – Kevin
    Sep 2, 2016 at 13:09

Your Answer

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

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