Is there a way to do that?
I'm try to create two pages as user/%/workspace and user/%/nodes, showing nodes created by user. user/%/workspace dedicated only for current user and can't be viewed by other. Instead they can view user/%/nodes, and user/%/nodes can't be accessed by user itself (there a workspace instead).
Both of views perfectly works as intended.
Now i'm try to assign this pages to tabs at /user page. And both tabs always present, regardless of what user looks at user's page. One of pages is empty, and i need to hide that page. How?

ps. sorry for my english...

Comments

dawehner’s picture

this is quite hard, especially for drupal6:
the Problem is that drupal6 doesn't support creating of menu items of the fly

but you could do something with your own hook_menu item and a custom title callback

merlinofchaos’s picture

Status: Active » Closed (won't fix)

Actually a custom access callback. The problem you run into is that the query will be run a lot more than you think it should, and could impact performance. Views won't support this itself, you'll need to use hook_menu and create your own menu item for this.

aschiwi’s picture

Is there any chance somebody can give some example code for this? Would it have to be a custom mini module, or rather a block with php content?

I'm working with Organic Groups to create work environments per group. I'm willing to hide the regular OG menu and create a custom menu which shows links to views if the view is not empty. If I knew php better, I would probably count the nodes of a certain type and if the count is bigger than 0, I would display the menu link.

momper’s picture

subscribing

aschiwi’s picture

Okay, I got this working with Views and a block and I'm sharing my code. It's probably not very pretty and most likely a little messy, but this is what I got.

Create a block. Put the following into the block body and set input type to php. This example includes calling two views.

<?php
if (module_exists('og')) {
  $group_node = og_get_group_context();
  $gid02 = $group_node->nid;
  $gid = (int)$gid02;
  if ($gid02 === null) $gid = 0;

  // load view object (has no results yet)
  $view = views_get_view('YOURVIEWNAMEHERE');
  $view_2 = views_get_view('YOURSECONDVIEWNAMEHERE');
  
  // set arguments (if needed, otherwise omit this line)
  $view->set_arguments(array($group_node->nid));
  $view_2->set_arguments(array($group_node->nid));
  
  // execute view query
  $view->execute();
  $view_2->execute();
  
  // results are now stored as an array in $view->result
  $count = count( $view->result );
  $count_2 = count( $view_2->result );

  $output .= '<ul class="menu">';

// if($count>0) means if the row count for this View is higher than 0 it outputs the link and otherwise nothing.

  if($count>0) {
    $output .= '<li class="leaf"><a title="Link" href="/node/$gid/first-view-url">Link ($count)</a></li>';
  }

  if($count_2>0) {
    $output .= '<li class="leaf"><a title="Link2" href="/node/$gid/second-view-url">Link2 ($count_2)</a></li>';
  }

  $output .= '</ul>';

  print $output;
}
?>

At the bottom of the block add this following code and make it "Show if the following PHP code returns TRUE (PHP-mode, experts only). " This makes the block show only on OG pages.

<?php
  $in_og = FALSE;
if (module_exists('og')) {
  $in_og = TRUE;
  $group_node = og_get_group_context();
  $gid02 = $group_node->nid;
  $gid = (int)$gid02;
  if ($gid02 === null) $gid = 0;
  if ($gid == 0) $in_og = FALSE;
}
return $in_og;
?>

I hope this is understandable.

brisath’s picture

Subscribing

SocialNicheGuru’s picture

subscribing

hellomobe’s picture

@3

I would probably count the nodes of a certain type and if the count is bigger than 0, I would display the menu link.

Is there a way to do this in the view as an argument? User:Id has a node of content type X > 0. If this argument isn't true than the view page is hidden (and the menu tab?) as part of the validation -- does it work this way?

merlinofchaos’s picture

Yes it does work this way, so your argument validation code could do this.

hellomobe’s picture

any idea of the code to do this - I don't see an option for node "count".

merlinofchaos’s picture

There's no option, you'd need to write validation code to do it.

whikloj’s picture

aschiwi, I just wanted to thank you for your code.

I did a modified version for a single view with multiple displays. I haven't tested performance, but the result is exactly what I wanted.

aac’s picture

Subscribing!!!

tomsm’s picture

I want to hide the menu tab when the view is empty.

Can someone help me with the validation code for the argument, please?

5t4rdu5t’s picture

I'm not sure about performance issues but this is at least a solution that works for me. I needed to hide tabs when there were no results on the view.

On the view's argument I chose PHP code as Validator and added the following code:


<?php 

$node = node_load($argument);
if($node->type =='mytype'){
  $result = db_query('SELECT * FROM content_type_mytype WHERE field_myfield_nid = %d', $argument);
  if(mysql_num_rows($result) > 0) return TRUE;
}
return FALSE;

?>

And set Action to take if argument does not validate: to Hide View / Page not found

lesleyfernandes’s picture

I have the same problem, but the argument is an uid.

lesleyfernandes’s picture

and if the argument is an uid?

5t4rdu5t’s picture

If your argument is an uid you'd just need to adjust the code accordingly. Make sure the SQL tries to fetch the same rows you're trying to retrieve with the view. Not an optimal solution but at least works.

<?php 
// Try to load the user
$user = user_load($argument);
// If user was loaded
if($user->uid){
  // Fetch rows to check if view is empty
  $result = db_query('SELECT * FROM node WHERE node.uid = %d', $argument);
  if(mysql_num_rows($result) > 0) return TRUE;
}
return FALSE;

?>

I wouldn't recommend this for large complex queries or heavily loaded servers...

5t4rdu5t’s picture

5t4rdu5t’s picture

melchoir55’s picture

Nice Libriana. #18 worked for me! I'm a little afraid of what will happen if my site gets a lot of traffic, but I guess I'll cross that bridge when I come to it.

melchoir55’s picture

I may have spoken too soon. #18 does indeed hide menu tabs. Unfortunately, it appears to be hiding the tabs whether or not they contain content!

I wonder if this is because the view is simply showing the content (body) of a node?

Update: I think I have thought up code that will work. I just don't know php well enough to actually write this:
php validator-

  if uid is member of role P, return TRUE
else return FALSE 

Is there anyone who could actually put together this code for me? I'm going to go start working on trying to piece it together, but I'd appreciate help if anyone can levy it.

5t4rdu5t’s picture

@melchoir55, are you trying to restrict access based on the current user roles?

If that's the case, have you tried setting the roles on the Access settings of the view? That should do the trick.

In case you need to check some other conditions together with user roles, you can add code to your argument like this

<?php

global $user;

if (in_array('role name', array_values($user->roles)) && $other_condition ) return TRUE;

?>
melchoir55’s picture

Thanks for the response libriana.

I have a view that has tabs. These tabs are themselves simply views of different content types which only a special kind of user can create, and these tabs attach to user profiles. . Each special user can create one and only one of each content type. Consequently, the view just filters content type: P and displays node:body in the field. The argument is uid pulled from url, since I want to display tabs created by the user being viewed, not by the user logged in. It all works fine, the only problem is that the tabs display on user profiles even when they haven't created any of the content pages (because they don't have permission to do so and never will).

I think that the problem is similar to OP. So, I figured your code above would have worked. For some reason, it just hides the tabs. They don't become visible when content is present.

P.S. I should mention the tabs are created using views itself. This is done by adding a "page" display then setting the "menu" entry to "menu tab".

5t4rdu5t’s picture

Ah... now I have a more clear picture of your situation :) Then the condition you want to check for is whether the node already exists for that uid and content type. The code on #18 should have worked for you, although you'd still need to check for the type. In case you're not very familiar with SQL or accessing the db directly, you can also try using node_load.

First, make sure your argument is fetching the uid from the url (guess you've already done so). Then go like this on the php validation:


<?php

$node = node_load(array('uid' => $argument , 'type' => 'mytype'));

if ($node->nid):
  return TRUE;   // the node was loaded 
else:
  return FALSE;  // the node does not exist
endif;

?>

This should work for you.

melchoir55’s picture

Thanks again for the response libriana. I don't know whether I'm messing up something really simply, but 25 did not work for me either. I am pulling the uid from url (in the argument section) and I'm filtering based on type: mytype (in the filters section). I'm displaying content Node: Body (in the fields section).

When I dump your code into the php validator through User:Uid argument, all it does is hide my tab entirely. I'm sure I'm doing something fundamentally wrong here, just not sure what.

However! I have managed to pull off what I wanted to do anyway and it is probably less resource intensive. In the User: Uid argument I chose "user" as the validator, then I restricted the view based on user role (a simple checkbox in this validator) and selected the roles whose profiles I wanted to display my tab. This worked perfectly.

Edit:

I should point out that this doesn't do exactly what the OP wanted. That is, the procedure I outline will not hide tabs because they are empty. It will only hide certain kinds of tabs when the user is viewing a profile who's owner cannot normally create those tabs.

The result is that empty tabs will still be present for users who could make the content but haven't done so. This isn't a problem for me, because all my users that have permission to create this content do so.

Shane Birley’s picture

I have been testing this since last week and I have found that there appears to be an issue with Views in how it is conducting the looping in the PHP solutions. I am still debugging and will post anything I find.

Another thing I will mention is that this may need to be a feature request since the overall question is how to hide a view should there be no content, regardless of how that is determined.

monsta_militia’s picture

Hello,
It didn't work because you have to remove from you input php code view. Spending one hour but it work for me :)

pippal’s picture

I have a Project page with an Events tab to show all events that node reference to that project. To hide the events tab if the view is empty I have the following in my argument php validation:


if(is_numeric($argument)){
  $result = db_query("SELECT node.nid AS nid, node.type AS node_type, node.vid AS node_vid FROM node node  LEFT JOIN content_field_noderef node_data_field_noderef ON node.vid = node_data_field_noderef.vid WHERE (node_data_field_noderef.field_noderef_nid IS NOT NULL) AND (node.type in ('event')) AND (node_data_field_noderef.field_noderef_nid = %d )", $argument);
  if(db_fetch_array($result) != NULL) return TRUE;
}
return FALSE;

I copied the SQL from another view I created, seems to work. Thought I'd paste it here in case any one else finds it useful, I searched around a lot for an answer this was one of the few threads I found useful.

I have no idea what the effect on performance will be... :/ Any ideas?

gMaximus’s picture

Hi...

I'm using marketplace where the Seller role can create the content type "products".

I've created a view that lists all products from a seller using their user id from the url as an argument. Then set it as a tab on the users profile, called "shop". I used the path users/%/shop. This works really well btw for others interested, when you include some exposed filters...

Anyway, the problem as you may have guessed already is that the profile tab "shop" is now shown on every bodies profile. Reading this page, it makes sense that the empty tab "shop", would go away on buyers profiles if I knew a little bit of php, for a second argument... Basically hide the view and tab if empty, would work perfectly, as buyers would never be able to create products...

I can't tell you much I'd appreciate some guidance...

Guy

gMaximus’s picture

Hi... I've been attempting to adapt your php validation to my site, in order to hide a empty profile tab / view...

Can i ask what does %d stand for in your SQL... Reminds me of getting a timestamp to display just the day or something...

I'm a noobie to PHP and this is the first time I've tried the php validator in views... I do understand SQL reasonably well though...

Also, what did you select as the argument? ie User:UID, Node: NID, Global: Null...

Can't tell you how much I'd appreciate any guidance....

gMaximus’s picture

Ah ha...

So i just worked out that by changing the type of validation to user, I could just tick the boxes for the roles who should have this tab... This in my case was the seller role....

Wanted to share and hope this helps others....

Guy

Petroslib’s picture

Hello i am using an argument Content:Has taxonomy term ID (with depth) please can you advice me how i edit the php code to hiding tab when view is empty

 $node = node_load($argument);if($node->type =='mytype'){  $result = db_query('SELECT * FROM content_type_mytype WHERE field_myfield_nid = %d', $argument);  if(mysql_num_rows($result) > 0) return TRUE;}return FALSE;

thanks in advance

geek-merlin’s picture

Title: Hiding tab when view is empty? » Hiding tab when view is empty
Version: 6.x-2.3 » 7.x-3.x-dev
Category: support » feature
Status: Closed (won't fix) » Active

I consider this a valid and often wanted feature request against current views.
Although earl verdicted a wontfix in #2, i see reasons to reconsider in the light of current menu integration and caching.

UI:
* Given a page display
* under "access"
* there should be a checkbox "prevent access when view is empty"
* with a big red sign "this can seriously affect performance, be sure to use caching"

elvismdev’s picture

The feature request by @axel.rutz is just what i am looking for at this moment in my project, i also would love to see this implemented in views.

Zythyr’s picture

Issue summary: View changes

Subscribing.

Has anyone found a solution for this?

geek-merlin’s picture

Title: Hiding tab when view is empty » Option to prevent view access (eg to hide tab) when view is empty
Project: Views (for Drupal 7) » Drupal core
Version: 7.x-3.x-dev » 8.5.x-dev
Component: Miscellaneous » views.module

Moving to views-in-core.

Zythyr’s picture

@axel.rutz Moving to views-in-core? Does that mean the request feature/issue won't be fixed for Views in Drupal 7?

geek-merlin’s picture

> Does that mean the request feature/issue won't be fixed for Views in Drupal 7?

New features are added at current version, then backported.

arua13l’s picture

Subscribing. Thanks. Looking for Version 7.x

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Deno’s picture

As far as I can see, this is still not resolved in Drupal 8.5.4. Any idea if or when it will be resolved?

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

W01F’s picture

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

wxman’s picture

I was just going to ask this question when I found this. Has this issue been worked on at all?

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.