views:

329

answers:

3

I have a Drupal 6.14 site with Views module. I have a view and on the primary links I put a link to the view.

There is a way to hide the link in the primary menu only if the view is empty?

+2  A: 

I am ready to be contradicted any moment as I never implemented anything like that, however I am under the impression that since views are essentially queries against the DB, you can't actually know if a view is empty until you actually invoke it.

Consider that - given you are speaking about primary links (shown on nearly every page of your site) this might be a serious performance hit, depending on the complexity of the view and on its "cacheability".

You should also consider whether the content of that view can be changed by other users browsing the site at the same time that "our" user: should the view become populated after "our" user has loaded the page, "our" user won't ever know.

As on how to achieve what you want, please see the accepted answer.

HTH!

mac
Using hook_menu_alter to do this would not keep up with the dynamic nature of views since menus are cached. For example, if a view has no results when the menu router is built, the implementation of menu_alter would not add the item. Then, if the view suddenly started returning results, that item wouldn't be added to the menu until the menus were rebuilt.
jhedstrom
+1 for pointing the performance hit
dusan
@jhedstrom - Good point about the cache! It is good that I was "ready to be contradicted any moment" then! I edited the original post and inserted a line pointing to your answer so that future reader will not get confused.
mac
+3  A: 

You could probably do this either via a theme or module implementation of preprocess_page (THEMENAME_preprocess_page(&$vars) or MODULENAME_preprocess_page(&$vars)), but mac above is correct in that views are not known to be empty or not until they are run, so there will be a performance hit.

Within the function, you should have access to the structured primary links array, so you can run the view:

 $view = views_get_view('view_name');
 // Swap out 'default' for a different display as needed. Also, $args are arguments, and can be left out if not applicable.
 $output = $view->preview('default', $args);
 if (empty($view->result)) {
   // The view has no results, alter the primary links here to remove the link in question.
 }
jhedstrom
+1, but one additional remark: `$view->preview` does not only build the view, but also renders it, which is unnecessary overhead. `$view->execute` will populate the result property as well, but saves the extra processing time for theming it (it just builds and runs the query).
Henrik Opel
A: 

I override views_embed_view() to only provide output if there is content, and then call my override from the theme layer:

function mymodule_embed_view($name, $display_id = 'default') {
  // handle any add'l args (this hook supports optional params)
  $args = func_get_args();
  array_shift($args); 
  if (count($args)) {
    array_shift($args); 
  }
  $view = views_get_view($name);
  $output = $view->preview($display,$args);
  if ($view->result) {
    return $output;
  }
}

Then in the template file:

<?php 
  $view = mymodule_embed_view('view_name');     
  if (strlen($view) > 0) {
    print $view;
  }
?>
threecheeseopera

related questions