Hi all,

I've already a working solution, but I have to know if there is a better way (performance, logic) to accomplish that.

What I've done:

  1. Make a view with "node/%/my-tab" path
  2. Create a simple TAB menu with that view (in node navigation)
  3. Create a helper module
  4. Implement hook_module_implements_alter() to run hook_menu_alter() after Views
  5. Implement hook_menu_alter() to intercept the TAB menu 'access callback' and provide my custom access callback (helper_access)
  6. Make the function helper_access() to manage the 'access callback' and manage conditions:
function helper_access() {
  if (arg(0) == 'node' && arg(1)) {
    $node = node_load(arg(1));
    if($node->type == 'allowed-type') {
      // check if Views return resuts:
      $view = views_get_view('my_view');
      $view->set_display('my_display');
      $view->args = array(arg(1));
      $output = $view->preview();
      if ($view->result) {
        return TRUE; // ok, show TAB menu
      }
    }
  }
  return FALSE; // hide TAB menu
}

All works fine, but is the above the correct way to accomplish that?

Thank you very much for helping

Comments

dawehner’s picture

Status: Active » Closed (duplicate)

Well the problem is that views might use some empty text, see #1217394: Change notice: "Display even if view has no result" not working which will provide a method for it.

iaminawe’s picture

MXT I would appreciate it if you would post your full helper module solution to this as I cannot seem to find a technique anywhere that works for this and I would like a little more clarification as to how you achieved this.

benjamin.pauley’s picture

I know this issue is closed, but the question of how to hide the menu tab of a Views content pane on a Panels page seems to be one that lots of people have asked about, so I hope maybe this can be helpful. I'm not positive this addresses exactly what the OP was inquiring about, but I think it does, and I accomplished it without a custom module.

1) Go to the Edit view for the Page on which you're trying to selectively hide the menu tab.

2) On Settings>Access, select "PHP Code" and then click "Add."

3) Supply an informative title.

4) Enter PHP code:

$view = views_get_view('my_view_name');
$view->set_display('my_display_name'); //e.g., 'panel_pane_1'
//NOTE: What you supply as an argument will depend on the page you're working with.
// In my case, the url takes the form of /entity_type/bundle/entity_id, so I'm using arg(2).
$view->args = array(arg(2)); 
$output = $view->preview();
//This next line is to deal with a problem I was having where a seemingly-empty view was, nonetheless,
//returning a result (a blank line). I think if my Views chops were better, I might be able to figure out
//why this was happening and squash it. But this worked for me. We're checking the first result (result[0])
//to see if a particular field (one that should have content if there are legitimate results) is actually NULL, instead:
//if the field is NULL, there are no real results we want to show, so we'll return FALSE and the menu tab will be hidden.
//If the field *isn't* NULL, then we'll return TRUE and the menu tab will be shown.
if (is_null($view->result[0]->field_field_in_the_view)) {
  return FALSE;
} 
else {
return TRUE;
}

5) Save and update.

I hope that helps...

jodyfr’s picture

Thanks, benjamin pauley, your PHP code was a big help. For those who might not know, you'll need to have the Views PHP module installed first.

jodyfr’s picture

Issue summary: View changes

Small typo

seandm’s picture

Issue summary: View changes

Thank You Benjamin. Works perfectly and seemingly very lightweight. Though it did cause a fatal error on the actual view page and needed to add a tiny bit of logic to the top of the PHP Code. Recommend installing The Devel Module as well to poke around with dpm(VARIABLE_NAME);

aksdax’s picture

You could do the same under hook_menu_local_task in the theme.
I was facing same issue wanted a way to hide tabs with no results.
I got it working this way for all tabs on website.

function YOUR_THEME_menu_local_task($variables) {
  $link = $variables['element']['#link'];
  $link_text = $link['title'];
  
  $page_args = unserialize($link['page_arguments']); // Gets the view name and display type
  // Could be useful if we want to restrict it to certain views and displays.

  $view = views_get_view($page_args[0]);
  $view->set_display($page_args[1]);
  $output = $view->preview();
/* If result is empty return here this hides the tab from showing up. However the page will still be visible when someone tries to visit the page directly. If we want to completely hide the view then the above solution is more appropriate. 
*/
 if (empty($view->result)) {   
    return;
  }
   // code to genrate your li or however the theme creates tab markup

  return "<li>" . l($link_text, $link['href'], $link['localized_options']) . "</li>";
}

May be same can be done under hook_menu_local_tasks_alter

mhkc’s picture

Hi - any thoughts on what adjustment could be made if you're not using field display (using teaser, for example)?

I've implemented the solution from #3 in an organic groups (tabbed menu) view. It works perfectly on a version where I'm using fields in the display, but chokes on exactly the same view that uses teaser display instead. It will show/hide the tab just fine, but is stuck in "whirling loading doom" when you try to access the content that's under the tab.

I'm sure there's a connection missing somewhere... any ideas? Thanks!

MmMnRr’s picture

Just a comment about solution in comment #6:
Between the following lines you may need to add an argument for the view, because when you add tabs to your node pages you are using contextual filters: "node/%/mytab". Usually, you will need the Node ID:

(...)
$args = arg();
$node_id = $args[0]; // the Node ID

$view->set_display($page_args[1]);
$view->args = array($node_id);
$output = $view->preview();
(...)

Otherwise, your tab will never appear because the view will be always empty (i.e. no contextual filter is received).

rickdrup’s picture

#3 works for hiding the tab when the view is empty but as in #5 and #7 the view results in a 503 fatal error when the tab is clicked if the view is not empty. Can anyone point me in the right direction to show the contents of the view when it is not empty?